Getting invalid token on Expo app

I’m implementing Auth0 authentication on a new Expo app following this example:

It seems to make a call to Auth0 and successfully obtain a token but immediatelly after logging the response in the console, it also gives me the following error:

Possible Unhandled Promise Rejection (id: 0)
[InvalidTokenError: Invalid token specified: Unexpected token V in JSON at position 0]

The response I get is this:
params:
access_token: “Vku7HOclH7pVi52bmzGHga89VwpfK_Y4”
exp://10.0.0.215:19000/–/expo-auth-session: “”
expires_in: “7200”
scope: “openid profile”
token_type: “Bearer”
proto: Object
type: “success”
url: “exp://10.0.0.215:19000/–/expo-auth-session#access_token=Vku7HOclH7pVi52bmzGHga89VwpfK_Y4&scope=openid%20profile&expires_in=7200&token_type=Bearer”

When I check the access_token on jtw.io, it indicates an invalid signature. Any idea what may be the issue here?

Here’s my full code:

import React, { Component } from 'react';
import { AuthSession } from 'expo';
import { Alert, Button, View, Text } from 'react-native';
import jwtDecoder from 'jwt-decode';

import styles from '../constants/styles';

const auth0ClientId = 'my_client_id_for_my_mobile_app_from_Auth0_dashboard';
const auth0Domain = 'https://mydomain.auth0.com';

  /**
   * Converts an object to a query string.
   */
function toQueryString(params) {
  return '?' + Object.entries(params)
    .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
    .join('&');
}

export default class Login extends Component {

  constructor(props) {

    super(props);
    this.state = {
      username: null
    };
  }

  _loginWithAuth0 = async () => {
    
    const redirectUrl = AuthSession.getRedirectUrl();
    console.log(`Redirect URL (add this to Auth0): ${redirectUrl}`);
    const result = await AuthSession.startAsync({
      authUrl: `${auth0Domain}/authorize` + toQueryString({
        client_id: auth0ClientId,
        response_type: 'token',
        scope: 'openid profile',
        redirect_uri: redirectUrl,
      }),
    });

    console.log(result);
    if (result.type === 'success') {
      this.handleParams(result.params);
    }
  }

  handleParams = (responseObj) => {
    
    if (responseObj.error) {
      Alert.alert('Error', responseObj.error_description
        || 'something went wrong while logging in');
      return;
    }
    const encodedToken = responseObj.access_token;
    const decodedToken = jwtDecoder(encodedToken, { header: true });
    const username = decodedToken.name;
    debugger;
    this.setState({ username });
  }

  render() {
    return (
      <View style={styles.welcomeScreen}>
        <Text>Welcome to My Expo App!</Text>
        <Button title="Login with Auth0" onPress={this._loginWithAuth0} />
      </View>
    );
  }
}

P.S. My Expo app is using SDK version 31.0.0

The sample you linked seems to expect the legacy, non OIDC-Conformant pipeline to work. See (and apply) the changes at this pull request for the sample to work: Fixed for OIDC by cocojoe · Pull Request #20 · expo/auth0-example · GitHub

Note, however, that this sample uses the implicit flow, which is not the recommended flow for native apps. By using this flow, you are potentially exposing the user information to other apps on the device (and doesn’t let you use refresh tokens). See Mobile Apps and OAuth’s Implicit Flow | by Justin Richer | Medium for a discussion on the risks.

I see that this issue was brought upon in Authorization Code Grant Flow with PKCE · Issue #16 · expo/auth0-example · GitHub, but no solution so far.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.