使用Next-Auth实现OAuth时出现意外302错误
NextJS集成Google登录时持续出现302错误
问题描述
使用NextJS搭建带Google登录功能的网站,点击登录按钮后反复出现意外302错误。
相关截图
- 首页截图:

- 错误截图:

相关代码片段
Nav客户端组件
"use client"; import Link from "next/link"; import Image from "next/image"; import { useEffect, useState } from "react"; import { signIn, signOut, useSession, getProviders } from "next-auth/react"; const Nav = () => { const { data: session } = useSession(); const [providers, setProviders] = useState(null); const [toggleDropdown, setToggleDropdown] = useState(false); useEffect(() => { const initProviders = async () => { const response = await getProviders(); setProviders(response); } initProviders(); }, []) return ( <nav className='flex-between w-full mb-16 pt-3'> <Link href='/' className='flex gap-2 flex-center'> <Image src='/assets/images/logo.svg' alt='logo' width={30} height={30} className='object-contain' /> <p className='logo_text'>Rate My Landlord</p> </Link> {/* Desktop Navigation */} <div className='sm:flex hidden'> {session?.user ? ( <div className='flex gap-3 md:gap-5'> <Link href='/create-prompt' className='black_btn'> Create Post </Link> <button type='button' onClick={signOut} className='outline_btn'> Sign Out </button> <Link href='/profile'> <Image src={session?.user.image} width={37} height={37} className='rounded-full' alt='profile' /> </Link> </div> ) : ( <> {providers && Object.values(providers).map((provider) => ( <button type='button' key={provider.name} onClick={() => { signIn(provider.id); }} className='black_btn' > Sign in </button> ))} </> )} </div> {/* Mobile Navigation */} <div className='sm:hidden flex relative'> {session?.user ? ( <div className='flex'> <Image src={session?.user.image} width={37} height={37} className='rounded-full' alt='profile' onClick={() => setToggleDropdown(!toggleDropdown)} /> {toggleDropdown && ( <div className='dropdown'> <Link href='/profile' className='dropdown_link' onClick={() => setToggleDropdown(false)} > My Profile </Link> <Link href='/create-prompt' className='dropdown_link' onClick={() => setToggleDropdown(false)} > Create Prompt </Link> <button type='button' onClick={() => { setToggleDropdown(false); signOut(); }} className='mt-5 w-full black_btn' > Sign Out </button> </div> )} </div> ) : ( <> {providers && Object.values(providers).map((provider) => ( <button type='button' key={provider.name} onClick={() => { signIn(provider.id); }} className='black_btn' > Sign in </button> ))} </> )} </div> </nav> ); }; export default Nav;
NextAuth配置文件
import NextAuth from 'next-auth'; import GoogleProvider from 'next-auth/providers/google'; import { db } from '@utils/database'; const handler = NextAuth({ providers: [ GoogleProvider({ clientId: process.env.GOOGLE_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, }) ], callbacks: { async session({ session }) { console.log("session"); const sessionUser = await db.user.findUnique({ where: { email: session.user.email } }); session.user.id = sessionUser._id.toString(); return session; }, async signIn({ account, profile, user, credentials }) { console.log("sign in"); try { console.log(profile); const result = await db.user.findUnique({ where: { email: profile.email } }); console.log(result); if (!result) { console.log("the user is no found in the database"); await db.user.create({ data: { email: profile.email, name: profile.name, } }); } return true } catch (error) { console.log("Error checking if user exists: ", error.message); return false } }, } }) export { handler as GET, handler as POST }
已在谷歌搜索数小时,未找到有效解决方案。
解决方案与调试步骤
1. 修复NextAuth回调错误处理
session回调未做错误捕获,若数据库查询失败会直接抛出错误引发302重定向。添加错误处理:
async session({ session }) { try { console.log("session"); const sessionUser = await db.user.findUnique({ where: { email: session.user.email } }); if (sessionUser) { session.user.id = sessionUser._id.toString(); } return session; } catch (error) { console.error("Session callback error:", error); return session; } },
2. 验证Google OAuth重定向URI
登录Google Cloud Console,检查OAuth客户端的授权重定向URI是否匹配:
- 开发环境:
http://localhost:3000/api/auth/callback/google - 生产环境:
https://你的域名/api/auth/callback/google
URI不匹配是302循环的最常见诱因。
3. 确认环境变量加载
检查.env.local中的GOOGLE_ID和GOOGLE_CLIENT_SECRET是否拼写正确、已生效。可在signIn回调中添加日志验证:
console.log("Loaded Google ID:", process.env.GOOGLE_ID);
4. 完善用户创建逻辑
Google返回的profile包含头像字段,但当前创建用户时未保存,若数据库模型要求该字段会导致创建失败,触发signIn回调返回false引发重定向。修改创建逻辑:
await db.user.create({ data: { email: profile.email, name: profile.name, image: profile.picture // 匹配数据库模型字段 } });
5. 指定登录回调URL
修改signIn调用,显式指定回调URL避免重定向异常:
onClick={() => signIn(provider.id, { callbackUrl: '/' })}
调试技巧
- 打开浏览器网络标签,追踪302重定向的完整路径,定位异常环节。
- 查看服务端日志,检查
signIn、session回调中的打印信息,确认哪一步出错。
内容的提问来源于stack exchange,提问作者Andrew Cheng
相关产品推荐
相关产品推荐

