我正在尝试使用@supabase/srr 进行身份验证。 在文档中,登录/注册表单应该是服务器组件,因为它调用登录和注册服务器操作 https://supabase.com/docs/guides/auth/server-side/nextjs
import { login, signup } from './actions'
export default function LoginPage() {
return (
<form>
<label htmlFor="email">Email:</label>
<input id="email" name="email" type="email" required />
<label htmlFor="password">Password:</label>
<input id="password" name="password" type="password" required />
<button formAction={login}>Log in</button>
<button formAction={signup}>Sign up</button>
</form>
)
}
我想在这个表单中使用zod,但是useForm钩子(来自react-hook-form)显然是客户端,我也使用了一些有状态的值。
那么这里有什么好的做法呢?从客户端组件调用我的操作不是问题吗? 或者我应该让我的 actions api 端点?或任何其他解决方案?
从客户端组件调用服务器操作是常见的做法。您可以将表单数据传递给服务器操作,然后在服务器端验证它。我将提供两种常见的方式。第一个将使用 ssr,第二个将使用客户端
1.从ssr组件调用登录动作
import { z } from "zod";
const loginSchema = z.object({
email: z.string().email("Invalid email format"),
password: z.string().min(6, "Password must be at least 6 characters long"),
});
export default function LoginPage() {
async function login(formData: FormData) {
'use server';
const rawFormData = {
email: formData.get("email"),
password: formData.get("password")
};
// Validate data
const result = loginSchema.safeParse(rawFormData);
if (!result.success) {
// Handle validation errors
return;
}
const validatedData = result.data;
// Proceed with login logic using validatedData
}
return (
<form action={login}>
<label htmlFor="email">Email:</label>
<input id="email" name="email" type="email" required />
<label htmlFor="password">Password:</label>
<input id="password" name="password" type="password" required />
<button formAction={login}>Log in</button>
</form>
);
}
2.客户端调用登录动作(也是正常、通用、安全的方式)
"use client";
import { login } from "@/components/actions";
export default function LoginPage() {
async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault();
const formData = new FormData(event.currentTarget);
try {
await login(formData);
console.log("Login successful");
// Redirect or update the UI on success
} catch (error) {
console.error("Login failed:", error);
// Display error message in the UI
}
}
return (
<form onSubmit={handleSubmit}>
<label htmlFor="email">Email:</label>
<input id="email" name="email" type="email" required />
<label htmlFor="password">Password:</label>
<input id="password" name="password" type="password" required />
<button type="submit">Log in</button>
</form>
);
}