Next.js next-auth在Vercel生产环境遇CLIENT_FETCH_ERROR,Google登录异常
Next.js 集成 NextAuth 部署到 Vercel 生产环境后出现 CLIENT_FETCH_ERROR
问题描述
本地环境功能正常,但部署到Vercel生产环境后出现以下异常:
- 点击调用
signIn('google')的按钮时,未弹出Google登录窗口,直接跳转至/api/auth/error页面 - 控制台报
CLIENT_FETCH_ERROR,提示JSON.parse解析异常,向/api/auth/session发送POST请求返回405错误
相关代码
pages/api/auth/[...nextauth].ts
import NextAuth, { NextAuthOptions } from 'next-auth'; import CredentialsProvider from 'next-auth/providers/credentials'; import Google from 'next-auth/providers/google'; import { gql } from '@apollo/client'; import client from '@/lib/apollo-client'; const secret = process.env.NEXTAUTH_SECRET; const LOGIN_MUTATION = gql` mutation Login($username: String!, $password: String!) { login(username: $username, password: $password) { token user { id username email } } } `; declare module "next-auth" { interface Session { id: string; username: string; email: string; accessToken: string; } } export const authOptions: NextAuthOptions = { providers: [ CredentialsProvider({ name: 'Credentials', credentials: { username: { label: 'Username:', type: 'text', placeholder: 'your username', }, password: { label: 'Password:', type: 'password', }, }, async authorize(credentials) { const { username, password } = credentials || { username: null, password: null }; try { const { data } = await client.mutate({ mutation: LOGIN_MUTATION, variables: { username, password }, }); const { token, user } = data.login; if (user) { return { id: user.id, username: user.username, email: user.email, token, }; } else { return null; } } catch (error) { console.error('Login error:', error); return null; } }, }), Google({ clientId: process.env.GOOGLE_CLIENT_ID as string, clientSecret: process.env.GOOGLE_CLIENT_SECRET as string, profile(profile) { const username = profile.email.split('@')[0]; return { id: profile.sub, email: profile.email, username, }; }, }) ], pages: { signIn: '/login', error: '/login' }, callbacks: { async signIn({ user, account, profile }) { return true; }, async jwt({ token, user }: { token: any; user: any }) { if (user) { token.id = user.id; token.username = user.username; token.email = user.email; token.accessToken = user.token; } return token; }, async session({ session, token }: { session: any; token: any }) { if (token) { session.id = token.id; session.username = token.username; session.email = token.email; session.accessToken = token.accessToken; } return session; }, async redirect({ url, baseUrl }) { return baseUrl; }, }, session: { strategy: 'jwt', }, secret, jwt: { secret, maxAge: 60 * 60 * 24 * 7, } } export default async function auth(req: any, res: any) { return NextAuth(req, res, authOptions); }
触发错误的按钮代码
<button onClick={() => signIn('google')} className="bg-blue-500 text-white px-8 py-4 rounded-lg shadow-lg flex flex-row mb-5" > <FcGoogle className='text-2xl'/><h2>Google</h2> </button>
控制台错误信息
[next-auth][error][CLIENT_FETCH_ERROR] JSON.parse: unexpected character at line 1 column 1 of the JSON data Object { error: {…}, url: "/api/auth/session", message: "JSON.parse: unexpected character at line 1 column 1 of the JSON data", client: true } _app-b6853d7412a1048d.js:1:30260 NextJS 8 error e e h value S t u [next-auth][error][CLIENT_FETCH_ERROR] JSON.parse: unexpected character at line 1 column 1 of the JSON data Object { error: {…}, url: "/api/auth/session", message: "JSON.parse: unexpected character at line 1 column 1 of the JSON data" } cinemation-3.vercel.app:13851:25 overrideMethod https://cinemation-3.vercel.app/:13851 NextJS 34 error e e h value S t u (Async: promise callback) t s (Async: promise callback) t s exports exports fetchData e h value S t s exports exports D e h value S t s exports exports e r
已做排查
- 配置了Vercel环境变量,包括
NEXTAUTH_SECRET、GOOGLE_CLIENT_ID、GOOGLE_CLIENT_SECRET - OAuth2客户端授权重定向URI设置为
https://xxx.vercel.app/api/auth/callback/google - MongoDB已设置允许所有IP访问
解决方案
1. 修复代码语法错误
原代码中LOGIN_MUTATION的gql模板字符串缺少闭合反引号,生产环境编译后会返回非JSON内容,直接引发JSON.parse异常,已在上述代码中修正。
2. 修正/api/auth/session请求方法
/api/auth/session仅支持GET请求,控制台出现POST请求405错误,需检查客户端代码中useSession或自定义获取session的逻辑,确保使用GET方法发起请求。
3. 验证Vercel环境变量有效性
- 确认
NEXTAUTH_SECRET、GOOGLE_CLIENT_ID、GOOGLE_CLIENT_SECRET等变量在Vercel中已正确配置,且部署时触发了重新构建(环境变量修改后需重新部署才会生效) - 生产环境必须设置
NEXTAUTH_SECRET,否则JWT签名验证会失败,导致session获取异常
4. 调整Google OAuth配置
- 确认Google Cloud控制台中,OAuth客户端的
授权重定向URI与Vercel生产域名完全一致,包含https前缀 - 检查OAuth客户端是否已发布到生产环境(未发布的客户端仅允许测试用户登录)
5. 修改redirect回调逻辑
当前redirect回调强制返回baseUrl,会破坏Google登录后的重定向流程,修改为:
async redirect({ url, baseUrl }) { if (url.startsWith(baseUrl)) return url; return baseUrl; }
6. 检查Apollo Client生产配置
若Credentials登录也存在异常,需确认Apollo Client在生产环境的API地址配置正确,避免因跨域或地址错误导致请求失败,影响NextAuth的authorize流程。
内容的提问来源于stack exchange,提问作者malle2002
相关产品推荐
相关产品推荐

