Next-Auth getSession在编辑接口失效问题排查与修复求助
Next-Auth 会话异常排查:GET接口可获取Session,PUT接口返回undefined
问题描述
我在学习TypeScript,使用Next.js开发Profile页面时遇到Next-Auth异常:调用获取用户信息的/api/getProfile接口时,getSession能正常获取会话;但调用编辑用户名的/api/editProfile接口时,getSession返回undefined。
差异原因分析
- Cookie传递配置缺失:axios默认在GET请求中自动携带Cookie,但PUT请求未配置
withCredentials: true,导致会话Cookie无法传递到后端,getSession无法识别用户身份。 - 接口安全校验缺失:
editProfile接口未先校验会话是否存在就执行数据库操作,既无法及时发现会话异常,还存在安全漏洞——恶意用户可通过篡改前端传入的userId修改他人信息。 - 异常处理不完善:
editProfile接口中User.findById(id)可能返回null,直接修改属性会触发运行时错误,且无全局异常捕获逻辑。
修复方案
前端修复(Profile组件)
修改PUT请求配置,添加withCredentials: true确保会话Cookie被传递:
const handleSubmit = async (e: React.FormEvent) => { // EDIT USER e.preventDefault() try { setLoading(true) // 新增withCredentials配置,确保Cookie传递 await axios.put('/api/editProfile', {userId, editName }, { withCredentials: true }) getData() setEditName('') setLoading(false) // 成功后更新loading状态 } catch (error) { console.log(error) setLoading(false) } }
额外优化:为getData的GET请求也添加相同配置,避免后续出现类似问题:
const res = await axios.get('/api/getProfile', { withCredentials: true })
后端修复(editProfile接口)
添加会话校验、基于会话身份获取用户、完善异常处理:
import { NextApiRequest, NextApiResponse } from "next" import User from "@/modules/User" import {connectToMongoDB} from '../../utils/db' import { getSession } from 'next-auth/react'; const handler = async (req: NextApiRequest, res: NextApiResponse) => { // 限制仅PUT方法访问 if (req.method !== 'PUT') { return res.status(405).json({ message: 'Method not allowed' }) } const session = await getSession({ req }); // 校验会话是否存在 if (!session) { return res.status(401).send('Signin required'); } const { user } = session; const email = user?.email if (!email) { return res.status(400).json({ message: 'Invalid user email' }) } try { await connectToMongoDB() // 确保数据库连接成功后执行操作 // 通过会话中的邮箱获取用户,避免依赖前端传入的ID,提升安全性 const profile = await User.findOne({ email }) if (!profile) { return res.status(404).json({ message: 'User not found' }) } const { editName } = req.body if (!editName) { return res.status(400).json({ message: 'Username is required' }) } profile.username = editName await profile.save() res.status(200).json({ message: 'Success', data: profile }) } catch (err) { console.error(err) res.status(500).json({ message: 'Internal server error' }) } } export default handler
额外优化建议
- 前端
useEffect添加session依赖,会话状态变化时自动重新获取用户信息:
useEffect(() => { if (session) { // 确保会话存在时再调用接口 getData() } },[session])
内容的提问来源于stack exchange,提问作者erza
相关产品推荐
相关产品推荐

