我刚刚在我的 nextjs14 项目上安装了 Authjs v5;设置如文档所述,并且处于基本状态,我没有在配置文件中添加任何内容。 问题是当我尝试登录时,出现以下错误:错误:
headers
在请求范围之外被调用。了解更多:https://nextjs.org/docs/messages/next-dynamic-api-wrong-context。
如何解决这个问题呢?我检查了文档,但找不到任何有用的信息。
//my handler in a clinet component
function handleLogin(e) {
e.preventDefault();
signIn("credentials", { email, password });
// auth.js setup
import NextAuth from "next-auth";
import Credentials from "next-auth/providers/credentials";
export const { handlers, signIn, signOut, auth } = NextAuth({
providers: [
Credentials({
credentials: {
email: {},
password: {},
},
authorize: async (credentials) => {
let user = {email: credentials.email}
console.log(user)
return user;
},
}),
],
});
我在app/api/[...nextauth]/route.js中有route.js文件
import { handlers } from "@/auth"; // Referring to the auth.ts we just created
export const { GET, POST } = handlers;
问题出在哪里?
尝试测试登录功能,我希望在授权功能中看到我的用户凭据。
我怀疑您在尝试在客户端上执行身份验证逻辑的文件顶部有“使用客户端”,而您无法使用 Authjs 服务器端身份验证来执行此操作,这就是导致您看到的错误的原因。
我已经使用一些服务器端逻辑并向其发出 POST 请求来解决它。
重要提示:我对 Authjs 的
redirectTo
有问题,所以我使用; 获取会话
const session = await auth();
并将其作为 props 传递给我的 AuthForm.ts(客户端组件),并使用
useEffect
将用户发送到我的 /dashboard
路线。
<AuthForm session={session} />
客户端;
"use client";
import { useEffect, useState } from "react";
import Button from "../ui/Button";
import Input from "../ui/Input";
type AuthFormProps = {
session: any;
};
export default function AuthForm({ session }: AuthFormProps) {
const [email, setEmail] = useState<string>("");
const handleEmailSignIn = async (e: { preventDefault: () => void }) => {
e.preventDefault();
try {
const response = await fetch("/api/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ email: email }),
});
if (!response.ok) {
const errorData = await response.json();
console.error("Failed to send login link:", errorData);
return;
}
const data = await response.json();
console.log(data.message);
} catch (error) {
console.error("Fetch error:", error);
}
};
useEffect(() => {
if (session) {
window.location.href = "/dashboard";
}
}, [session]);
return (
<form onSubmit={handleEmailSignIn}>
<div className="flex flex-col gap-4 w-[300px]">
<Input
label={"Email"}
type="text"
name="email"
placeholder="[email protected]"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<Button cta="Send login link" type="submit" />
</div>
</form>
);
}
服务器端;
/api/login/route.ts
import { signIn } from "@/app/auth";
import { NextRequest, NextResponse } from "next/server";
export async function POST(request: NextRequest) {
try {
const data = await request.json();
const email = data.email;
await signIn("sendgrid", { email, redirect: false });
return new NextResponse(
JSON.stringify({
message: "Check your email for the login link!",
}),
{
headers: {
"Content-Type": "application/json",
},
status: 200,
}
);
} catch (error) {
console.error("Error during sign-in:", error);
return new NextResponse(
JSON.stringify({
error: "Failed to send email",
message: error,
}),
{
headers: {
"Content-Type": "application/json",
},
status: 500,
}
);
}
}