使用Next-Auth、Next.js和Vercel时遇JsonWebTokenError: invalid signature错误
JWT令牌验证失败(仅Vercel生产环境异常,开发环境正常)
我在API请求中遇到JWT令牌无法验证的问题,具体情况如下:
- 已从next-auth的
session.user.accessToken获取令牌,并在请求头中携带authorization字段 - 其他采用相同JWT验证逻辑的项目运行正常
- 仅在Vercel部署的生产环境出现错误,开发环境完全正常
- 已尝试重新登录,问题依旧
- Next-Auth使用的
NEXTAUTH_SECRET与JWT工具函数使用的SECRET_KEY为不同密钥,且生产/开发环境的密钥保持一致
相关代码
Next-Auth配置
export const options: NextAuthOptions = { adapter: PrismaAdapter(prisma), providers: [ CredentialsProvider({ id: "credentials", name: "Credentials", type: "credentials", credentials: { email: {label: "email", type:"email", placeholder: "name@example.com"}, password: {label: "password", type: "password", placeholder:"password"} }, async authorize(credentials) { const res = await fetch(envCheck()+"/api/login", { method:"POST", headers: { "Content-Type": "application/json", }, body:JSON.stringify({ email: credentials?.email, password: credentials?.password, }) }); console.log("response from authorize",res); // Will show you the status if(res.status === 200) { const user = res.json(); return user; } else { throw new Error(""+res.status); } }, }) ], secret: process.env.NEXTAUTH_SECRET, session: { strategy: "jwt", maxAge: 30 * 24 * 60 * 60, }, pages: { signIn: '/auth', signOut: '/' }, callbacks: { async jwt({token, user, trigger, session}) { if(trigger === "update") { return {...token, ...session.user} } return({...token, ...user}) }, async session({session, token}) { session.user = token as any; return session; } } }
JWT工具函数
interface SignOption { expiresIn?: string | number; } const DEFAULT_SIGN_OPTION: SignOption = { expiresIn: "1h" } export function signJwtAccessToken(payload: JwtPayload, options?:SignOption) { const secret_key = process.env.SECRET_KEY; const token = jwt.sign(payload, secret_key!, options); return token; } export function verifyJwt(token:string) { try { const secret_key = process.env.SECRET_KEY; const decoded = jwt.verify(token, secret_key!); return decoded as JwtPayload; } catch (error) { console.error(error); return null; } }
API请求示例
const response = await fetch(envCheck()+`/api/user/${session?.user.id}/gym`, { headers:{ "authorization": session.user.accessToken, }, });
令牌验证逻辑
const accessToken = request.headers.get("authorization") if(!accessToken || !verifyJwt(accessToken)) { return NextResponse.json("401"); };
内容的提问来源于stack exchange,提问作者marcellobonini
相关产品推荐
相关产品推荐

