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 finding work arounds on, everything has been going great. That is until it came to Authentication and Authorization. We got a pre-made small server that is hosted locally, and it had a JWT Token system set up for users. We did a POST request where we sent the registered email and password, and got back a token. 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.


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 the relevant code:

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)\]


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