Next-Auth页面刷新时如何更新refreshToken?
问题描述
概述
我已实现next-auth,从授权服务获取accessToken并将其作为参数传入mutation,后续API调用使用后端生成的token。
已按照next-auth的刷新令牌轮换机制实现了token轮换功能。
问题
我的token过期时间设为1分钟:
- 会话在后台运行未操作时,API能正常调用并更新新的
refreshToken(符合预期); - 但1分钟后刷新页面,会话会直接退出。
查看终端发现,页面刷新时旧refreshToken没有更新为新的,客户端仍保留刷新前的refreshToken,但后台运行时无此问题 😕
有没有解决方法?或者我哪里配置错误?
提前感谢!
代码片段
pages/api/[..nextauth].tsx代码
import NextAuth, { NextAuthOptions } from "next-auth" import { JWT } from "next-auth/jwt" import GithubProvider from "next-auth/providers/github" import { Provider, RefreshToken } from "../../../generated/graphql" const loginQuery = `mutation login($AccessToken: String!, $Provider: Provider!) { login(accessToken: $AccessToken, provider: $Provider) { refreshToken token tokenExpiry } }` const refreshTokenQuery = `mutation refreshToken($RefreshToken: String!) { refreshToken(refreshToken: $RefreshToken) { refreshToken token tokenExpiry } }` const authMutation = (query, variables) : Promise<RefreshToken | null> => { return fetch(process.env.NEXT_PUBLIC_API_URL, { method: 'POST', body: JSON.stringify({ query: query, variables: variables }) }) .then(res => res.json()) .then(data => { if (data.errors) { return null; } else { let response = data.data.refreshToken || data.data.login; if (response.refreshToken === undefined || response.tokenExpiry === undefined || response.token === undefined) return null return <RefreshToken> response; } }) .catch(error => { console.log(error); return null; }); }; async function login(account, user: any) { let provider: Provider; if (account?.provider === 'github') provider = Provider.GitHub if(provider === undefined) return const variables = { AccessToken: account.access_token, Provider: provider }; const response = await authMutation(loginQuery, variables) if (response === null) return console.log("new refresh token..", response.refreshToken) return { accessToken: response.token, accessTokenExpires: response.tokenExpiry * 1000, refreshToken: response.refreshToken, user, } } async function refreshAccessToken(token: any) { const variables = { RefreshToken: token.refreshToken, }; console.log("variables", variables) const response = await authMutation(refreshTokenQuery, variables) if (response === null) return console.log("new refresh token..", response.refreshToken) return { ...token, accessToken: response.token, accessTokenExpires: response.tokenExpiry * 1000, refreshToken: response.refreshToken, } } export const authOptions: NextAuthOptions = { providers: [ GithubProvider({ clientId: process.env.NEXT_PUBLIC_GITHUB_OAUTH_CLIENT_ID, clientSecret: process.env.NEXT_PUBLIC_GITHUB_OAUTH_CLIENT_SECRET, }), ], theme: { colorScheme: "light", }, callbacks: { jwt: async ({ account, token, user }: any): Promise<JWT> => { console.log("current refreshToken", token.refreshToken, token.accessTokenExpires) // Initial Sign In if (account && user) { console.log("initial login", account) return login(account, user) } // Return previous token if the access token has not expired yet if (Date.now() < token.accessTokenExpires){ console.log("token not expired") return token } // Rotate refresh_token and fetch new access_token if current one is expired if (token){ console.log("token expired") return refreshAccessToken(token) } }, session: async ({ session, token }: any) => { if (!session?.user || !token?.accessToken) return session.accessToken = token.accessToken as string session.error = token.error as string | undefined session.user = token.user return session }, }, } export default NextAuth(authOptions)
_app.tsx代码
import "../styles/globals.css" import { SessionProvider as NextSessionProvider } from "next-auth/react" import UrqlProvider from "../lib/provider" import { AppProps } from "next/app" function App({ Component, pageProps }: AppProps) { const { session } = pageProps return ( <> <NextSessionProvider session={session}> <UrqlProvider> <Component {...pageProps} /> </UrqlProvider> </NextSessionProvider> </> ) } export default App
内容的提问来源于stack exchange,提问作者Yeganathan S
相关产品推荐
相关产品推荐

