react-nativejwtfrontendbackend

jwtDecode - InvalidTokenError: Invalid token specified: invalid base64 for part #2 (Property ‘atob’ doesn’t exist)]


So I am following an online course on React Native from Mosh at Code with Mosh, and despite some things that have been outdated and I've had to find work arounds on, everything has been going great. That is until I reached one of the final chapters when it came to Authentication and Authorization. We got a premade small server that we host locally, and it had JWT Token system set up for users, which was all fine and good. We did a POST where we sent the registered email and password, and got back a token. And using jwt.io we could decode the token and get all of the information just fine. However, when I try to decode it using jwt-decode I just get back this error message, and I can't for the life of me understand why.


TLDR, the tokens can be decoded just fine online through places like jtw.io, but installing and using jtw-decode just gives me this message.

Here is my code: (I am skipping over some things that are irrelevant to the problem.)

import React, { useState, useContext } from "react";
import { Image, StyleSheet } from "react-native";
import \* as Yup from "yup";
import { jwtDecode } from "jwt-decode";

const handleSumbit = async ({ email, password }) =\> {
const result = await authApi.login(email, password);
if (!result.ok) return setLoginFailed(true);
setLoginFailed(false);

const token = result.data;
const decoded = jwtDecode(token);
console.log(decoded);
};

Expected output:

{user: name, ...}

Actual output:

Warning: An unhandled error was caught from submitForm() \[InvalidTokenError: Invalid token specified: invalid base64 for part #2 (Property 'atob' doesn't exist)\]

  • I have tried to log the token directly instead of into an const.
  • I have tried another decoder that I found, a similar issue occurred.
  • I have logged the token and manually decoded it on jwt.io, and it worked there without issues.

Solution

  • You need to poly-fill atob function using something like core-js.

    1. using core-js:
    import "core-js/stable/atob";
    import { jwtDecode } from "jwt-decode";
    
    const token = "eyJ0eXAiO.../// jwt token";
    const decoded = jwtDecode(token);
    
    console.log(decoded);
    
    1. using base-64:
    import { decode } from "base-64";
    
    global.atob = decode;
    

    Your code may look like:

    import React, { useState, useContext } from "react";
    import { Image, StyleSheet } from "react-native";
    import * as Yup from "yup";
    import { jwtDecode } from "jwt-decode";
    import "core-js/stable/atob"; // <- polyfill here
    
    const handleSumbit = async ({ email, password }) => {
      const result = await authApi.login(email, password);
    
      if (!result.ok) return setLoginFailed(true);
    
      setLoginFailed(false);
    
      const token = result.data;
      const decoded = jwtDecode(token);
      
      console.log(decoded);
    };
    

    Reference: https://github.com/auth0/jwt-decode#polyfilling-atob