Issue: /oauth/token returning 403 without any error message

Hello Everyone,

I’m currently developing a React Native-based mobile application, utilizing Auth0 as our authentication service. However, I’m encountering a significant issue with replacing expired access tokens with new ones. Despite extensive research through Auth0’s documentation and various articles, I haven’t been able to implement this in a production-ready manner.

The problem I’m facing involves the oauth/token endpoint returning a 403 status code. I’m unsure if I’m calling this endpoint correctly for obtaining a new access token and replacing the existing one. If this is the correct approach, I need guidance on how to fix the issue.

Here’s a summary of my current implementation:

Current Implementation

I’m using a custom hook to check if the token has expired and, if so, to update it with a new one.

javascript

Copy code

import Config from 'config';
import 'core-js/stable/atob'; // Polyfill since RN doesn't support atob 👉🏾 https://github.com/auth0/jwt-decode/issues/241
import { jwtDecode, JwtPayload } from 'jwt-decode';
import { captureSentryException } from 'sentry_telemetry/sentryLogger';
import { getAccessToken, getRefreshToken, setAccessToken, setRefreshToken } from '../storage/token';

export const useRefreshToken = () => {
  const accessToken = getAccessToken();
  const refreshToken = getRefreshToken();

  function isTokenExpired() {
    try {
      if (!accessToken) {
        return false;
      }
      const decoded = jwtDecode<JwtPayload>(accessToken);
      const currentTime = Date.now() / 1000; // current time in seconds
      return decoded.exp ? decoded.exp < currentTime : false;
    } catch (err) {
      console.error(err);
      return false;
    }
  }

  const getNewAccessToken = async () => {
    try {
      if (!refreshToken) {
        return;
      }

      if (!isTokenExpired()) {
        return;
      }

      const response = await fetch(`https://${Config.Auth0Domain}/oauth/token`, {
        method: 'POST',
        headers: {
          'content-type': 'application/x-www-form-urlencoded',
        },
        body: `grant_type=refresh_token&client_id=${Config.Auth0ClientId}&client_secret=${Config.Auth0SecretKey}&refresh_token=${refreshToken}`,
      });

      if (response.ok || response.status === 200) {
        const data = await response.json();
        setAccessToken(data.access_token);
        setRefreshToken(data.refresh_token);
        return { token: data?.access_token || '' };
      }
    } catch (err) {
      console.error(err);
      captureSentryException('Error in fetching new access token', err?.message);
    }
  };

  return { getNewAccessToken, isTokenExpired };
};

Any assistance from the community would be highly appreciated.

Thank you!