如何处理sidebase/nuxt-auth中refresh端点的自动请求错误?
在sidebase/nuxt-auth中处理刷新令牌错误并自动登出
sidebase/nuxt-auth基于next-auth实现,你可以通过扩展JWT回调和Session回调来处理刷新令牌失败的场景,自动触发登出操作,具体实现如下:
1. 配置JWT回调处理刷新逻辑
在项目的server/api/auth/[...].ts文件中,修改NuxtAuthHandler的配置,在jwt回调中实现令牌刷新,并捕获刷新失败的错误:
import { NuxtAuthHandler, signOut } from '#auth' import CredentialsProvider from 'next-auth/providers/credentials' export default NuxtAuthHandler({ providers: [ CredentialsProvider.default({ name: 'Credentials', credentials: { username: { label: 'Username', type: 'text' }, password: { label: 'Password', type: 'password' } }, async authorize(credentials: any) { // 替换为自研后端的登录校验逻辑 const response = await fetch('https://你的后端地址/login', { method: 'POST', body: JSON.stringify(credentials), headers: { 'Content-Type': 'application/json' } }) const user = await response.json() if (response.ok && user) { return user } return null } }) ], callbacks: { async jwt({ token, user, account }) { // 首次登录时保存令牌信息 if (account && user) { return { accessToken: account.access_token, refreshToken: account.refresh_token, expiresAt: Date.now() + account.expires_in * 1000, user } } // 令牌未过期,直接返回 if (Date.now() < token.expiresAt) { return token } // 尝试刷新令牌 try { const refreshResponse = await fetch('https://你的后端地址/refresh', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ refreshToken: token.refreshToken }) }) if (!refreshResponse.ok) { throw new Error('Refresh token invalid') } const newTokens = await refreshResponse.json() return { ...token, accessToken: newTokens.access_token, refreshToken: newTokens.refresh_token || token.refreshToken, expiresAt: Date.now() + newTokens.expires_in * 1000 } } catch (err) { // 刷新失败,标记错误状态 return { ...token, error: 'RefreshTokenError' } } }, async session({ session, token }) { // 将令牌数据同步到session session.accessToken = token.accessToken session.user = token.user // 检查到刷新错误,触发登出 if (token.error === 'RefreshTokenError') { await signOut({ redirect: false }) // 如需跳转登录页,可设置redirect: '/login' } return session } } })
2. 关键逻辑说明
- 在
jwt回调中,当令牌即将过期时发起刷新请求,捕获请求失败的异常,给token添加error: 'RefreshTokenError'标记 - 在
session回调中检查该标记,一旦发现则调用signOut执行登出操作 - 若需要登出后自动跳转登录页,可将
signOut的redirect参数设为目标路径(如'/login')
3. 额外提示
- 确保自研后端的refresh端点在令牌无效/过期时返回正确的HTTP错误状态码(如401 Unauthorized),这样
!refreshResponse.ok才能正确捕获错误 - 如果你需要在前端页面中处理登出后的状态,可以通过
useSession()钩子监听session变化,做相应的UI调整
内容的提问来源于stack exchange,提问作者Lucas
相关产品推荐
相关产品推荐

