如何使用 Okta 实现 Auth Code Flow

How to implement Auth Code Flow with Okta

我们有一个 React 应用程序,我们正在尝试通过 Facebook 社交登录来实现授权代码流。一旦通过身份验证,我们将向后端发出请求,后端将在每次调用时验证 JWT 访问令牌。

当尝试使用 Facebook 登录时,我们使用我们的授权代码成功重定向回 redirect_uri,但在我们能够将授权代码交换为访问令牌之前,我们收到以下错误:

AuthSdkError: Unable to retrieve OAuth redirect params from storage

我们有一个简单的组件来处理回调 URI 和 Okta 配置,如下所示:

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>
  );
}

错误似乎来自 Okta SDK 中的 LoginCallback 组件。

我们有一个 URL 这样的程序可以处理我们的登录并将我们重定向到我们的应用程序: 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

原来我应该使用 Okta 的 SDK 来生成授权字符串而不是自己构建它。 SDK 在幕后处理事情,特别是 PKCE 需要 code_verifier 存储在本地存储中,然后在用户成功登录后重定向到应用程序时提取。

这是我用 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
  });
};