我目前正在使用 Next.js 开发一个网站,并且正在使用 Next.js 应用程序路由器。我已经集成了 NextAuth 来处理登录,到目前为止,用户创建和登录工作正常。
但是,我在登录后设置重定向时遇到了问题。目前,当我单击登录按钮时,我的提取会将我直接重定向到“/profile”页面。但是,我想创建一个动态路由来将用户重定向到“/profile/[userName]”之类的内容。
为了实现这一目标,我在“pages”目录中创建了一个文件“[userName]”,其中包含“page.jsx”。这个想法是,登录后,它应该带我到“/profile/[userName]”。但是,问题是,当我使用以下命令时,它要么总是将我重定向到“http://localhost:3000/profile”,要么将我定向到“http://localhost:3000/profile/%5B%5D”我的提取中的代码:
router.push(
/个人资料/[${userSlug}]);
我也尝试过以下版本,但也不起作用:
router.push(
/个人资料/${String(userSlug)});
您能否帮助我理解为什么重定向未按预期工作以及如何解决此问题? 预先感谢您的帮助!”
这是我的登录页面:
"use client";
import { useState } from "react";
import { useFormik } from "formik";
import Image from "next/image";
import { signIn, useSession } from "next-auth/react";
import { useRouter } from "next/navigation";
import { redirect } from "next/navigation";
export default function Login({ params }) {
const session = useSession();
const { status } = useSession();
let slug;
const isAuthenticated = status === "Authenticated";
const userName = session.data?.user?.name;
const userSlug =
userName && userName.includes(" ")
? userName.split(" ")[0].toLowerCase()
: "";
if (isAuthenticated) {
return redirect("/");
}
const router = useRouter();
const [error, setError] = useState([]);
console.log("SESSION: ", session);
const handleSubmit = async () => {
const result = await signIn("credentials", {
email: formik.values.email,
password: formik.values.password,
redirect: false,
});
if (result.error == null) {
console.log("fetch", slug);
router.push(`/profile/${String(userSlug)}`);
}
setError(result.error);
};
const formik = useFormik({
initialValues: {
email: "",
password: "",
},
onSubmit: handleSubmit,
});
return (
<section className="mt-8">
<h1 className="text-center text-4xl mb-4">Login</h1>
<form
className="flex flex-col max-w-xs mx-auto"
onSubmit={formik.handleSubmit}
// onSubmit={handleSubmit}
>
{error && <div className="text-red-500">{error}</div>}
<input
type="email"
name="email"
placeholder="email"
value={formik.values.email}
// value={email}
onChange={formik.handleChange}
// onChange={(e) => setEmail(e.target.value)}
/>
<input
type="password"
name="password"
placeholder="password"
value={formik.values.password}
// value={password}
onChange={formik.handleChange}
// onChange={(e) => setPassword(e.target.value)}
/>
<button type="submit">Login</button>
<div className="my-4 text-center text-gray-500">
or login with provider
</div>
<button
type="button"
alt="google logo"
onClick={() => signIn("google", { callbackUrl: "/" })}
className="flex gap-4 justify-center"
>
<Image src={"/google.png"} alt={""} width={24} height={24} />
Login with google
</button>
</form>
</section>
);
}
这是我的身份验证route.js
import GoogleProvider from "next-auth/providers/google";
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import bcrypt from "bcrypt";
import { PrismaAdapter } from "@auth/prisma-adapter";
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
// export default NextAuth(authOptions);
const handler = NextAuth({
// Configure one or more authentication providers
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
}),
CredentialsProvider({
name: "credentials",
credentials: {
name: { label: "Name", type: "text" },
email: {
label: "Email",
type: "email",
placeholder: "[email protected]",
},
},
// ...
async authorize(credentials, req) {
// Check to see if email and password are valid
if (
!credentials.email ||
!credentials.password ||
credentials.email === "" ||
credentials.password === ""
) {
throw new Error("Email and password are required");
}
// Check to see if the user exists
const user = await prisma.user.findUnique({
where: {
email: credentials.email,
},
});
if (!user) {
throw new Error("User not found");
}
// Check to see if the password matches
const passwordMatch = await bcrypt.compare(
credentials.password,
user.password
);
if (!passwordMatch) {
throw new Error("Incorrect password");
}
// Return the user object if everything is valid
return user;
},
// ...
}),
// ...add more providers here
],
session: {
strategy: "jwt",
},
secret: process.env.NEXTAUTH_SECRET,
adapter: PrismaAdapter(prisma),
});
export { handler as GET, handler as POST };
我的尝试和期望(附加信息): 在尝试解决重定向问题时,我采取了以下操作:
我尝试将
userSlug
变量转换为字符串并在路线中使用它:
router.push(`/profile/${String(userSlug)}`);
但是,这并没有解决问题,重定向问题仍然存在。
作为测试,我直接在路由中设置用户名:
router.push("/profile/john");
令人惊讶的是,这按预期工作并将我重定向到“http://localhost:3000/profile/john。”
我尝试了不同的变化,包括从动态路线中删除方括号:
router.push(`/profile/${userSlug}`);
不幸的是,这也导致直接重定向到“http://localhost:3000/profile”,而不考虑动态值。
我从“profile”目录中删除了“page.js”文件,但这并没有给重定向行为带来任何变化。
当您知道用户已通过身份验证时,请使用 router.push()
if (isAuthenticated) {
router.push(`profile/${userSlug}`)
}