You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next-Auth v4.22.1+NextJS13服务端登出请求失败求助

问题:Next-Auth v4.22.1 + NextJS 13 服务端登出请求失败

背景

使用Next-Auth v4.22.1和NextJS 13,尝试在服务端实现用户登出功能,已知客户端signOut()方法无法在服务端调用(会触发ReferenceError: window is not defined),因此自行编写了/api/nextauth-signout-requests接口,通过POST请求调用/api/auth/signout,但请求失败。

错误信息

nextauth-signout-requests.js - Fetch Error SyntaxError: Unexpected token E in JSON at position 0
API handler should not return a value, received object.
API resolved without sending a response for /api/nextauth-signout-requests, this may result in stalled requests.

当前代码(nextauth-signout-requests.js)

const NextAuthSignOutReq = async (req, res) => {

    if (req.method === 'POST') {
        try {

            // Sign out the user
            const signOut = await fetch(`${HOMEPAGE_URL}/api/auth/signout?callbackUrl=${HOMEPAGE_URL}/api/auth/session`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Accept': 'application/json'
                },
                body: await fetch(`${HOMEPAGE_URL}/api/auth/csrf`).then(rs => rs.text())
            });


            const data = await signOut.json();

            if (signOut.status === 200) {
            
                // Success
                console.log('User Signed Out');

                return res.status(200);

            } else {

                // Fail
                console.log(`nextauth-signout-requests.js - POST to /auth/signout failed`);
                return res.status(500);
            }
        } catch(err) {

            // Fail
            console.log('nextauth-signout-requests.js - Fetch Error ' + err);
            return res.status(500);

        }
    } 
    else {
        // Error. Not a POST request. They tried GET or PUT etc.
        res.setHeader('Allow', ['POST']);
        return res.status(405).json({ 'error': `Method ${req.method} not allowed`});
    }

}

export default NextAuthSignOutReq;

问题原因与解决方案

1. JSON解析错误:Unexpected token E

你的猜测正确,/api/auth/signout默认返回的是HTML重定向页面,而非JSON数据,因此调用signOut.json()会触发解析错误。Next-Auth的signout端点核心逻辑是清除会话并跳转,不支持返回JSON格式响应。

2. CSRF令牌用法错误

服务端场景下无需通过fetch获取CSRF令牌,Next-Auth提供了服务端方法自动处理CS校验,手动传递的令牌格式也不符合要求(signout的POST请求需要表单格式的csrfToken参数,而非纯文本)。

3. API响应未正确结束

代码中return res.status(200);的写法错误,Next.js API路由必须调用end()或json()方法结束响应,否则会导致API resolved without sending a response错误。


修正后的服务端登出接口代码

import { signOut } from "next-auth/react";
import { getServerSession } from "next-auth/next";
import { authOptions } from "./auth/[...nextauth]"; // 导入你的NextAuth配置文件

const NextAuthSignOutReq = async (req, res) => {
  if (req.method === "POST") {
    try {
      // 验证用户是否已登录
      const session = await getServerSession(req, res, authOptions);
      if (!session) {
        return res.status(401).json({ error: "用户未登录" });
      }

      // 服务端调用signOut,自动处理会话清除与跳转
      await signOut({ 
        req, 
        res, 
        callbackUrl: `${process.env.HOMEPAGE_URL}/` // 登出后跳转的目标地址
      });

      // 如果不需要跳转,可手动清除会话Cookie(替代上面的signOut调用)
      // res.setHeader("Set-Cookie", [
      //   `next-auth.session-token=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; httponly`,
      //   `next-auth.csrf-token=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT`
      // ]);
      // return res.status(200).json({ success: true });

    } catch (err) {
      console.error("登出失败:", err);
      return res.status(500).json({ error: "登出操作失败" });
    }
  } else {
    res.setHeader("Allow", ["POST"]);
    return res.status(405).json({ error: `不支持${req.method}请求方法` });
  }
};

export default NextAuthSignOutReq;

关键说明

  • 服务端登出直接使用Next-Auth提供的signOut方法,传入req和res参数,它会自动处理CSRF校验、会话Cookie清除和页面跳转。
  • 若不需要跳转,可手动清除next-auth.session-token和next-auth.csrf-token两个Cookie,然后返回JSON响应。
  • 所有API响应必须通过res.status(...).json(...)或res.status(...).end()结束,避免请求挂起。

内容的提问来源于stack exchange,提问作者Scottish Smile

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 19:12:43