NextAuth和Next.js到动态路由的问题,如“http://localhost:3000/profile/%5B%5D”

gg58donl  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(88)

我目前正在使用Next.js开发一个网站,我正在使用Next.js应用程序路由器。我已经集成了NextAuth来处理登录,到目前为止,用户创建和登录都很完美。
然而,我在登录后设置重定向时遇到了一个问题。目前,当我单击登录按钮时,我的获取会直接将我重定向到“/profile”页面。但是,我想创建一个动态路由来将用户重定向到“/profile/[userName]"之类的页面。
为了实现这一点,我在“pages”目录中创建了一个文件“[userName]”,其中包含“page.jsx”。这个想法是,在登录时,它应该带我到“/profile/[userName]"。然而,问题是,它总是将我重定向到“http://localhost:3000/profile”,或者当我在fetch中使用以下代码时,它将我定向到“http://localhost:3000/profile/%5B%5D”:router.push(/profile/[${userSlug}] );我也试过以下版本,但也不起作用:router.push(/profile/${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>
  );
}

字符串

This is my auth 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 };

**我的尝试和期望(其他信息):**在尝试解决重定向问题时,我采取了以下操作:

1.我尝试将userSlug变量转换为字符串,并在路由中使用它:

router.push(`/profile/${String(userSlug)}`);


然而,这并没有解决问题,重定向问题仍然存在。
1.作为测试,我直接在路由中设置一个用户名:

router.push("/profile/john");


令人惊讶的是,这正如预期的那样工作,并将我重定向到“http://localhost:3000/profile/john”。
1.我尝试了不同的变化,包括从动态路由中删除方括号:

router.push(`/profile/${userSlug}`);


不幸的是,这也导致了直接重定向到“http://localhost:3000/profile”,而没有考虑动态值。
1.我从“profile”目录中删除了“page.js”文件,但这并没有带来重定向行为的任何变化。

i1icjdpr

i1icjdpr1#

当您知道用户在以下位置进行了身份验证时,请使用router.push()

if (isAuthenticated) {
    router.push(`profile/${userSlug}`)
  }

字符串

相关问题