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

使用NextAuth.js对接Strapi登录时出现CLIENT_FETCH_ERROR问题排查

NextAuth.js凭证认证CLIENT_FETCH_ERROR问题排查

问题场景

在Next.js(前端)+ Strapi(后端)的开发环境中配置NextAuth.js凭证认证,调用signIn函数登录用户时触发CLIENT_FETCH_ERROR。

相关配置与代码

1. .env配置

NEXT_PUBLIC_API_URL = http://127.0.0.1:1337/api
NEXTAUTH_URL = http://localhost:3000/
NEXTAUTH_SECRET =  

2. app/api/auth/[...nextauth].js

import CredentialsProvider from "next-auth/providers/credentials"
import NextAuth from "next-auth/next";

const authOptions = {
    session:{
        strategy:'jwt'
    },
    pages: {
        signIn: '/auth/signin',
    },
    providers: [
    CredentialsProvider({
        name: 'credentials',
        credentials: {
            email: { label: "email", type: "email", placeholder: "email" },
            password: { label: "Password", type: "password" }
            },

        async authorize(credentials, req) {

            const credentialDetails = {
                identifier: credentials.email,
                password: credentials.password,
            };

            const res = await fetch(process.env.NEXT_PUBLIC_API_URL + "/auth/local", {
                method: 'POST',
                body: JSON.stringify(credentialDetails),
                headers: { "Content-Type": "application/json" }
            })

        const user = await res.json()

        if (res.ok && user) {
            return user
        }
        return null
        }
    })
    ],
    secret: process.env.NEXTAUTH_SECRET,
    callbacks: {
        jwt: async ({ token, user }) => {
        if (user) {
            token.email = user.user.email;
            token.username = user.user.username;
            token.id = user.user.id;
            token.accessToken = user.jwt;
        }
        return token;
        },
        session: ({ session, token, user }) => {
            if (token) {
            session.user.email = token.email;
            session.user.username = token.username;
            session.user.id = token.id;
            session.user.accessToken = token.accessToken;
            }
            return session;
        },
    },
}

export default NextAuth(authOptions)

3. app/auth/signin/page.js

'use client'
import {React, useState} from 'react'
import  {signIn} from "next-auth/react"

function page() {

    const [data, setData] = useState({
        email : "",
        password : ""
    })

    const loginUser = (e) => {
        e.preventDefault();
        signIn('credentials', {
            email: data.email,
            password: data.password,
            redirect: false,
        })
    }

  return (
    <>
    <h1>Login</h1>
    <form method="post" onSubmit={loginUser}>
      <label>
        Email
        <input name="email" type="text" onChange={
            (e)=>{setData({...data,email:e.target.value})}
        } />
      </label>
      <label>
        Password
        <input name="password" type="password" onChange={
            (e)=>{setData({...data,password:e.target.value})}
        }/>
      </label>
      <button type="submit">Sign in</button>
    </form>
    </>
  )
}

export default page

错误原因与修复方案

1. 未配置NEXTAUTH_SECRET

NextAuth.js强制要求设置NEXTAUTH_SECRET,空值会导致认证流程中的加密/解密操作失败,直接触发CLIENT_FETCH_ERROR。

修复:
用openssl rand -hex 32命令生成随机密钥,填入.env:

NEXTAUTH_SECRET = 你的随机密钥字符串

2. Fetch请求未处理异常

当前authorize函数中,若Strapi服务未启动、网络不通或接口地址错误,fetch会抛出异常,但代码未捕获,导致NextAuth内部处理失败。

修复:
给fetch添加try/catch捕获异常:

async authorize(credentials, req) {
  try {
    const credentialDetails = {
      identifier: credentials.email,
      password: credentials.password,
    };

    const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/auth/local`, {
      method: 'POST',
      body: JSON.stringify(credentialDetails),
      headers: { "Content-Type": "application/json" }
    })

    const user = await res.json()

    if (res.ok && user) {
      return user
    }
  } catch (error) {
    console.error("Strapi接口请求失败:", error);
  }
  return null
}

3. 环境变量URL格式问题

NEXTAUTH_URL末尾的斜杠可能导致NextAuth内部路由解析异常,建议去掉:

NEXTAUTH_URL = http://localhost:3000

4. 登录请求未处理错误反馈

当前signIn调用后未处理返回结果,无法直观排查具体错误。可以添加错误捕获:

const loginUser = async (e) => {
  e.preventDefault();
  const result = await signIn('credentials', {
    email: data.email,
    password: data.password,
    redirect: false,
  })
  if (result.error) {
    console.error("登录错误:", result.error);
    // 可在此处给用户展示错误提示
  }
}

额外检查点

  • 确认Strapi服务正常运行在http://127.0.0.1:1337
  • 用Postman等工具测试Strapi的/api/auth/local接口是否可用
  • 检查防火墙/安全软件是否拦截了Next.js与Strapi之间的请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 23:55:24