如何使用Next Auth的POST /api/auth/signout端点实现无重定向登出?
Next Auth 无重定向登出实现方案
问题分析
你遇到的核心问题是Next Auth默认的/api/auth/signout端点会主动触发重定向,即便携带了CSRF令牌,也会跳转到指定登出页面,导致无法通过纯API调用完成无跳转登出。
解决步骤
要实现无重定向的API式登出,需要自定义Next Auth的API路由,覆盖默认登出逻辑:
- 创建自定义API路由
在项目的pages/api/auth目录下新建signout.ts(或.js)文件,替换默认登出端点:
import { NextApiRequest, NextApiResponse } from "next"; import { getServerSession } from "next-auth/next"; import { authOptions } from "./[...nextauth]"; // 导入你的Next Auth配置 export default async function handler(req: NextApiRequest, res: NextApiResponse) { if (req.method !== "POST") { return res.status(405).json({ error: "Method not allowed" }); } // 验证CSRF令牌(必须步骤,防止跨站请求伪造) const csrfToken = req.body.csrfToken; const session = await getServerSession(req, res, authOptions); if (!csrfToken || !session) { return res.status(401).json({ error: "Unauthorized" }); } // 执行登出操作:清除session和相关cookie await authOptions.session.destroy({ req, res }); // 返回成功响应,不触发重定向 return res.status(200).json({ success: true, message: "Signed out successfully" }); }
- 前端调用逻辑调整
前端需先获取CSRF令牌,再携带令牌调用自定义登出API:
// 获取CSRF令牌 const getCsrfToken = async () => { const res = await fetch('/api/auth/csrf'); const data = await res.json(); return data.csrfToken; }; // 无重定向登出函数 const signOutWithoutRedirect = async () => { const csrfToken = await getCsrfToken(); const res = await fetch('/api/auth/signout', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ csrfToken }), }); if (res.ok) { // 登出成功后的前端处理,比如清除本地状态、跳转首页等 console.log('登出成功'); // 示例:跳转到首页(可选,根据需求决定是否跳转) window.location.href = '/'; } else { const error = await res.json(); console.error('登出失败:', error); } };
关键说明
- CSRF令牌验证:必须保留CSRF令牌验证,这是Next Auth的安全要求,避免跨站请求伪造攻击。
- 自定义路由优势:通过覆盖默认登出端点,可完全控制响应逻辑,避免默认的重定向行为。
- 前端后续处理:登出成功后,可根据业务需求选择是否跳转页面,或仅更新前端状态。
内容的提问来源于stack exchange,提问作者Yanick Rochon
相关产品推荐
相关产品推荐

