Search code examples
javascriptreactjsoauth-2.0oauthokta

How to implement Auth Code Flow with Okta


We have a react app which we are trying to implement auth code flow with social logins with Facebook. Once authenticated We will make requests to our backend which will validate the JWT access token on each call.

When trying to login with Facebook, we get redirected back to our redirect_uri successfully with our auth code but before we are able to exchange the auth code for an access token we receive the following error:

AuthSdkError: Unable to retrieve OAuth redirect params from storage

We have a simple component that handles the callback URI and the Okta config like so:

const oktaAuth = new OktaAuth({
  clientId: CLIENT_ID,
  issuer: ISSUER,
  redirectUri: REDIRECT_URI,
  scopes: ['openid', 'profile', 'email'],
  pkce: true,
  disableHttpsCheck: OKTA_TESTING_DISABLEHTTPSCHECK,
});

function App() {

  const history = useHistory();

  const restoreOriginalUri = async (_oktaAuth: any, originalUri: any) => {
    history.replace(toRelativeUrl(originalUri || '/', window.location.origin));
  };

  return (
    <Security oktaAuth={oktaAuth} restoreOriginalUri={restoreOriginalUri}>
      <UserDataProvider>
        <Switch>
          <Route path="/" exact component={isAuthenticated ? Home : Login} />

          <SecureRoute path="/protected" exact component={Home} />
          <Route path="/login/callback" component={LoginCallback} /> // LoginCallback from the Okta SDK (@okta/okta-react)

          <Redirect to="/" />
        </Switch>
      </UserDataProvider>
    </Security>
  );
}

The error seems to be coming from LoginCallback component in the Okta SDK.

We have a URL like so that handles our login and should redirect us to our app: https://${ourOktaDomain}/oauth2/v1/authorize?idp=${idp}&client_id=${clientId}&response_type=code&response_mode=query&scope=openid%20email&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Flogin%2Fcallback&state=${randomString}&code_challenge=${anotherRandomString}&code_challenge_method=S256

  • Why are we getting this error?
  • What is Okta trying to retrieve from storage and which storage is it talking about (local / session etc).
  • Should we be setting some value in storage before redirecting to the aforementioned Okta login URL?
  • Is our OktaAuth config object correct? Is it correct to be using PKCE?

Solution

  • Turns out I should have been using Okta's SDK to generate the auth string rather than building it myself. The SDK handles things behind the scenes, specifically for the PKCE which requires a code_verifier be stored in local storage and then extracted when the user gets redirected to the app after a successful signin.

    This is how I handled it with the SDK:

    const onSocialLogin = () => {
      oktaAuth.signInWithRedirect({ 
        originalUri: '/welcome',
        clientId: CLIENT_ID,
        redirectUri: encodeURI(REDIRECT_URI),
        responseType: 'code',
        responseMode: 'query',
        state,
        nonce,
        codeChallenge,
        codeChallengeMethod: 'S256',
        scopes: ['openid', 'email'],
        idp: FACEBOOK_APP_ID
      });
    };