You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next-Auth令牌过期后无法重触发未授权请求问题求助

问题描述

令牌过期后可成功刷新,但Next-Auth出现以下异常:

  • 自动跳转至/sign-in页面
  • 触发401的GET请求持续返回“UnAuthorized”
  • 日志显示accessToken已刷新且会话已更新

当前已通过jwt回调实现令牌刷新逻辑,需求如下:

  • 让Next-Auth自动重触发导致401的请求
  • 全局管理令牌刷新,避免逐个响应检查令牌过期

现有配置代码

import NextAuth from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials"
import GoogleProvider from "next-auth/providers/google"
import { postRequest } from "../api_requests"
import { settings } from "app.config"
import jwtDecode from "jwt-decode"


const refreshAccessToken = async (token) => {
    const newAccessToken = await postRequest(
        `/auth/refresh`,
        { refreshToken: token.user.refreshToken },
        token.user.refreshToken
    )

    const newToken = newAccessToken.data ? newAccessToken.data : { error: "RefreshAccessTokenError" }
    return newToken
}

const providers = [
    CredentialsProvider({
        name: "Credentials",
        credentials: {
            username: { label: "用户名", type: "text", placeholder: "请输入用户名..." },
            password: { label: "密码", type: "password" }
        },
        async authorize(credentials, req) {
            const { username, password } = credentials
            const { statusCode, data: user } = await postRequest('/auth/signin', {
                user: username,
                password
            })

            if (user && (statusCode === 200 || statusCode === 201)) {
                return user
            } else {
                return null
            }
        }
    })
]


const callbacks = {
    jwt: async ({ token, user, account, trigger, session }) => {
        // 首次登录时将用户信息存入token
        user && (token.user = user)

        // 客户端触发会话更新时,同步用户资料
        if (trigger === "update") {
            return { ...token, user: session.user }
        }

        // ===== 令牌过期处理 ===== //
        // 解析令牌过期时间,计算剩余有效时长
        const { exp } = jwtDecode(token?.user?.accessToken)
        const shouldRefreshTime = Math.round((exp * 1000) - Date.now())
        console.log({ shouldRefreshTime })

        // 访问令牌已过期,执行刷新逻辑
        if (shouldRefreshTime <= 0) {
            const newToken = await refreshAccessToken(token)
            console.log({ newToken })
            token.user = {
                ...token.user,
                ...newToken
            }
        }

        // 令牌仍有效则直接返回
        return token
    },
    session: async ({ session, token }) => {
        session && (session.user = token.user)  // 将令牌中的用户信息同步到会话
        return session;
    },
}

export const authOptions = {
    secret: settings.env.nextAuthSecret,
    // 配置认证提供者
    providers,
    session: {
        strategy: "jwt",
    },
    pages: {
        signIn: "/authentication/sign-in"
    },
    callbacks,
}

export default NextAuth(authOptions)

内容的提问来源于stack exchange,提问作者osomaher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 14:52:59