next.js15:在服务器Action

问题描述 投票:0回答:1

I使用next.js 15。如下所示,我将服务器操作“ Onlogin”传递给了称为“登录名”的客户端组件。当用户单击表单中的登录按钮时,该操作是调用的。在服务器操作中,我实例化了一个身份验证程序类,该类负责将提供的凭据发送到服务器,并使用cookie()。设置(“ ...”)保存接收到的访问令牌并返回身份验证状态。如果身份验证成功,客户端组件将将用户发送到下一页。在我的理解中,我遵循有关在服务器操作中操纵cookie的文档。但是,我遇到了“只能在服务器操作或路由处理程序中修改cookie”。我想念什么?是因为我将身份验证流委托给身份验证类别类别吗?与示例相比,这是我看到的唯一区别。奇怪的是,这种确切的实现以前起作用并停止工作,而我却没有意识到我所做的任何更改。

export async function LoginPage() { async function onLogin(state: LoginFormState, formData: FormData): Promise<LoginFormState> { "use server"; const username = formData.get("username")?.toString(); const password = formData.get("password")?.toString(); const authenticator = new Authenticator() return authenticator.authenticate(username, password) }; return ( <LoginForm formAction={ onLogin }/> ); }
在这里客户组件

'use client'; export function LoginForm({ formAction }: Props) { const [isRejected, setIsRejected] = useState(false); const [state, action] = useActionState<LoginFormState, FormData>(formAction, {}); const router = useRouter() useEffect(() => { if (state.errorState?.unauthorized) { setIsRejected(true) } if (state.successState) router.push('/clients') }, [state]); return ( <div className="flex h-screen"> <div className="secondary-color-background m-auto p-8 sm:rounded-md flex flex-col justify-center items-center"> <form action={action} className=""> <label className="block mb-6"> <span className="h2 white-color">Username</span> <input name="username" type="text" className={`${state.errorState?.username ? "border-orange" : ""} w-full border-2 rounded p-2 focus:outline-none focus:bg-white focus:border-primary `} placeholder="type here"/> </label> <label className="block mb-6"> <span className="h2 white-color">Password</span> <input name="password" type="password" className={`${state.errorState?.password ? "border-orange" : ""} w-full border-2 rounded p-2 focus:outline-none focus:bg-white focus:border-primary `} placeholder="type here" /> </label> <div className="flex flow-root w-full content-start items-end"> <ShakeButton text="Inloggen" isShaking= { isRejected } onStop= { () => setIsRejected(false) }/> <Link className="body2 text-primary ml-4" href={"/komt nog"}> Ik ben mijn wachtwoord vergeten </Link> </div> </form> </div> </div> ); }
    
next.js cookies server-action
1个回答
0
投票
看起来您正在关注下一个。JS15文档正确,但是问题可能是由于修改了身份验证器类中的cookie而不是服务器操作。

因子:cookies必须在服务器操作中设置 next.js需要cookie()。设置(...)在服务器操作的执行范围内运行。如果在Authenticator中进行处理,则Next.js不会将其识别为有效的修改。 有可能的解决方案1:

移动cookie()。设置(...)到服务器操作 像这样更新Onlogin:

export async function LoginPage() { async function onLogin(state: LoginFormState, formData: FormData): Promise<LoginFormState> { "use server"; const username = formData.get("username")?.toString(); const password = formData.get("password")?.toString(); const authenticator = new Authenticator(); const result = await authenticator.authenticate(username, password); if (result.success && result.token) { import("next/headers").then(({ cookies }) => { cookies().set("access_token", result.token, { httpOnly: true, secure: true }); }); } return result; }; return <LoginForm formAction={onLogin} />; }

为什么这有效:

cookie现在设置在服务器操作中。

authenticator仅返回令牌而不是修改cookie。

Import(“ Next/headers”)确保正确访问Cookie()。
  • 有可能的解决方案2:
  • 将Onlogin移至顶部“使用服务器”的新文件,然后在登录页中导入它:
  • // actions/auth.ts "use server"; import { cookies } from "next/headers"; import { Authenticator } from "@/lib/authenticator"; export async function onLogin(state: LoginFormState, formData: FormData): Promise<LoginFormState> { const username = formData.get("username")?.toString(); const password = formData.get("password")?.toString(); const authenticator = new Authenticator(); const result = await authenticator.authenticate(username, password); if (result.success && result.token) { cookies().set("access_token", result.token, { httpOnly: true, secure: true }); } return result; }
,然后在loginpage.tsx中使用它: 导入{onLogin}来自“@/action/auth”;

export function LoginPage() { return <LoginForm formAction={onLogin} />; }

我建议使用第三种方法,因为它保持适当的执行范围,同时保持代码清洁和有条理。但是,这可能需要在您的目的上进行一些重构。 Feel免费尝试最适合您的方法,并希望这有帮助!
	

© www.soinside.com 2019 - 2024. All rights reserved.