刷新令牌后,下一个身份验证令牌不会持续存在

问题描述 投票:0回答:1

我目前正在开发 nuxt 应用程序,我需要将其与客户提供商集成以进行身份验证(OAuth)。对于身份验证,我使用 next-auth(AuthJs),一切工作正常,当刷新此应用程序所需的

access_token
时,它失败了。
access_token
的有效期为2小时

jwt
回调中,将
refreshed_token
分配给
token
并传递给
sesssion
回调后。但在下一个会话检查(自动运行)中,jwt 回调中的令牌具有旧值。初始登录时指定的值将保留。但至于刷新就成了问题了。

由于该值不会通过

refresh_token
重新分配,所以
expire_at
属性也是如此。所以它会不断刷新令牌,直到它使最初的
refresh_token
无效。

这个问题有解决办法吗?

为什么初始登录中的值(返回)(正在检查回调中的

account
参数)运行良好并且令牌被保留?

server/api/auth/[...].ts

import type { AuthConfig, TokenSet } from "@auth/core/types";
import { NuxtAuthHandler } from "#auth";
import { JWT } from "@auth/core/jwt";

const runtimeConfig = useRuntimeConfig();
const BASE_URL = "Base url";

async function refreshAccessToken(token: JWT): Promise<TokenSet> {
  const params = new URLSearchParams({
    client_id: process.env.NUXT_AUTH_CLIENT_ID!,
    client_secret: process.env.NUXT_AUTH_CLIENT_SECRET!,
    grant_type: "refresh_token",
    refresh_token: token.refresh_token as string,
  });
  const response = await fetch(`${BASE_URL}/oauth/token`, {
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: params.toString(),
    method: "POST",
  });
  const tokens: TokenSet = await response.json();

  if (!response.ok) {
    throw tokens;
  }
  return {
    ...token,
    access_token: tokens.access_token,
    refresh_token: tokens.refresh_token,
    error: null,
    expires_at: Math.floor(Date.now() / 1000 + 30), // 30 for testing
    // expires_at: Math.floor(Date.now() / 1000 + tokens.expires_in!),
  };
}

export const authOptions: AuthConfig = {
  secret: runtimeConfig.authJs.secret,
  debug: true,
  callbacks: {
    async jwt({ token, account }) {
      console.log('-----------------------------------');
      
      console.log("token in jwt is ", token);

      const now = Date.now();
      let resToken = null;
      if (account) {
        console.log("initial login", token, account);

        // Initial login
        resToken = {
          ...token,
          access_token: account.access_token,
          refresh_token: account.refresh_token,
          expires_at: Math.floor(Date.now() / 1000 + 30),
          // expires_at: Math.floor(Date.now() / 1000 + account.expires_in!),
          error: null,
        };
      } else if (now < (token.expires_at as number) * 1000) {
        console.log("token is valid ", token);

        // Have valid token
        resToken = token;
      } else {
        // RefreshToken
        try {
          console.log("before refresh token is ", token);
          // the returned refreshed token is not persisting so expires_at, access_token and refresh_token remains the same as the first
          // So this code blocks keeps running for around 3 times as the expires_at not changed
          // it will invalidate the accessToken and refresh token it becomes a "RefreshAccessTokenError"
          resToken = await refreshAccessToken(token);
          console.log("resToken is ", resToken);
          console.log('-----------------------------------');
          
        } catch (error) {
          console.error("Error refreshing access token", error);
          return { ...token, error: "RefreshAccessTokenError" as const };
        }
      }
      return resToken;
    },
    async session({ session, token }) {
      return {
        ...session,
        access_token: token.access_token,
        refresh_token: token.refresh_token,
        error: token.error,
      };
    },
  },

  providers: [
    {
      id: "projectId",
      name: "projectName",
      type: "oauth",
      issuer: BASE_URL,
      clientId: process.env.NUXT_AUTH_CLIENT_ID,
      clientSecret: process.env.NUXT_AUTH_CLIENT_SECRET,
      token: `${BASE_URL}/oauth/token`,
      authorization: {
        url: `${BASE_URL}/oauth/authorize`,
        params: { scope: "api_v3" },
      },
      redirectProxyUrl: "http://localhost:3000/api/auth",
      userinfo: `${BASE_URL}/api/v3/users/me`,
    },
  ],
};

export default NuxtAuthHandler(authOptions, runtimeConfig);

authentication next.js jwt nuxt.js next-auth
1个回答
0
投票

通过禁用 ssr 解决多重快速会话检查

© www.soinside.com 2019 - 2024. All rights reserved.