NextJS重定向和更新更改不适用于Strapi Apollo GraphQl身份验证

发布于 2025-02-12 22:20:33 字数 10837 浏览 0 评论 0原文

我正在对NextJS strapi GraphQl实现身份验证,并且一旦用户注册或登录或其中的用户是cookie中的JWT令牌,但是当我登录时。它不是使用路由器的重定向。 系统信息 4.1.11: macos: mysql: 14.17.00: 6.14.13: 1.22.19:

import { useContext, useEffect, useState } from "react";
import Image from "next/image";
import Link from "next/link";
import { useMutation } from "@apollo/client";
import { LOGIN_USER } from "../../gql/mutations";
import { userContext } from "../../context/wrapppers/UserWrapper";
import { setUserAction } from "../../context/actions/user-actions";
import { SIGN_IN } from "../../context/actions/action-types";

import { useRouter } from "next/router";

function login() {
  const router = useRouter();
  const { user, dispatchUser } = useContext(userContext);
  const [credentials, setCredentials] = useState({});

  useEffect(() => {
    if (user !== "" && user !== undefined) {
      router.push("/account");
    }
  }, []);

  const [loginUser, { loading, error, data }] = useMutation(LOGIN_USER);

  useEffect(() => {
    if (data) {
      dispatchUser(
        setUserAction(
          {
            token: data.login.jwt,
            username: data.login.user.username,
            id: data.login.user.id,
            email: data.login.user.email,
          },
          SIGN_IN
        )
      );
    }
  }, [data]);

  if (loading) return <h1>logging in...</h1>;
  if (error) return <h1>{error.message}</h1>;

  console.log("user from login page", user);

  const handleChange = (e) => {
    setCredentials({
      ...credentials,
      [e.target.name]: e.target.value,
    });
  };

  const handleLogin = (e) => {
    if (typeof window === "undefined") {
      return;
    }
    e.preventDefault();
    loginUser({
      variables: {
        input: credentials,
      },
    });
  };

  return (
    <div className="h-screen bg-slate-50 flex justify-center items-center w-full">
      {error && <div>{error.message}</div>}
      <form onSubmit={handleLogin}>
        <div className="bg-white px-10 py-8 rounded-xl w-screen shadow-md max-w-sm">
          <Image
            src={require("../../public/Img/logo.png")}
            height={50}
            objectFit="contain"
            className="h-14 mb-4 mx-auto"
            alt=""
          />
          <div className="space-y-4">
            <h1 className="text-center text-2xl font-semibold text-gray-600">
              Login
            </h1>
            <div>
              <label
                for="email"
                className="block mb-1 text-gray-600 font-semibold"
              >
                Email or Username
              </label>
              <input
                name="identifier"
                onChange={handleChange}
                type="text"
                required
                className="bg-indigo-50 px-4 py-2 outline-none rounded-md w-full"
              />
            </div>
            <div>
              <label
                for="password"
                className="block mb-1 text-gray-600 font-semibold"
              >
                Password
              </label>
              <input
                name="password"
                onChange={handleChange}
                type="text"
                required
                className="bg-indigo-50 px-4 py-2 outline-none rounded-md w-full"
              />
            </div>
          </div>
          <button
            type="submit"
            className="mt-4 w-full bg-yellow-500 font-semibold py-2 rounded-md  tracking-wide"
          >
            Login
          </button>
          <Link href="account/register">
            <h3 className="mt-2 cursor-pointer">Or Create an account</h3>
          </Link>
        </div>
      </form>
    </div>
  );
}

export default login;

function index() {
  const router = useRouter();
  const { user, dispatchUser } = useContext(userContext);

  const [getUserOrders, { loading, error, data }] = useLazyQuery(USER_ORDERS);
  useEffect(() => {
    if (user) {
      getUserOrders({
        variables: {
          filters: {
            user: {
              id: {
                eq: user.id,
              },
            },
            status: {
              ne: "rejected",
            },
          },
        },
      });
    } else {
      router.push("/account/login");
    }
  }, [user]);

  if (error) return <div>{error.message}</div>;
  if (loading) return <div>Loading ...</div>;

  const handleLogout = () => {
    router.push("/account/login");
    dispatchUser(setUserAction(user, SIGN_OUT));
  };


    return (
      <div>
        <section className="py-5 sm:py-7 bg-gray-100">
          <div className="container max-w-screen-xl mx-auto px-4">
            Home/Account
          </div>
        </section>

        <section className="py-10">
          <div className="container max-w-screen-xl mx-auto px-4">
            <div className="flex flex-col md:flex-row -mx-4">
              <aside className="md:w-1/3 lg:w-1/4 px-4">
                <ul>
                  <li>
                    <Link href="/account">
                      <span className="block px-3 py-2 text-primary bg-gray-100 hover:bg-orange-100  rounded-md">
                        Account
                      </span>
                    </Link>
                  </li>
                  <li>
                    <div
                      className="cursor-pointer flex items-center"
                      onClick={handleLogout}
                    >
                      <IoIosLogOut size="20" className="mr-2" />
                      <span>Log out</span>
                    </div>
                  </li>
                </ul>
              </aside>
              <main className="md:w-2/3 lg:w-3/4 px-4">
                <article className="border border-gray-200 bg-white shadow-sm rounded mb-5 p-3 lg:p-5">
                  <figure className="flex items-start sm:items-center">
                    <AiOutlineUser size="50" />
                    <figcaption>
                      <h5 className="font-semibold text-lg">
                        Hi {user.username}
                      </h5>
                      <p>Email: {user.email}</p>
                    </figcaption>
                  </figure>

                  <hr className="my-4" />

                  <h3 className="text-xl font-semibold mb-5">Order History</h3>

                  {data && data.orders.data.length !== 0 ? (
                    data.orders.data.map(({ id, attributes }, orderIndex) => (
                      <article
                        key={id}
                        className="p-3 lg:p-5 mb-5 bg-white border border-blue-600 rounded-md"
                      >
                        <header className="lg:flex justify-between mb-4">
                          <div className="mb-4 lg:mb-0">
                            <p className="font-semibold">
                              <span>Order ID: #{id} </span>
                              <span className="text-green-500">
                                {" "}
                                • {attributes.status}{" "}
                              </span>
                            </p>
                            <p className="text-gray-500">
                              {" "}
                              {new Date(
                                attributes.createdAt
                              ).toLocaleDateString()}
                            </p>
                          </div>
                        </header>

                        <hr className="my-4" />

                        <div className="grid md:grid-cols-2 lg:grid-cols-3 gap-2">
                          {attributes.products.data.map(
                            ({ id, attributes }, productIndex) => (
                              <Link href={`/shop/${attributes.slug}`}>
                                <figure
                                  key={id}
                                  className="flex flex-row mb-4 cursor-pointer"
                                >
                                  <div>
                                    <Image
                                      src={`${
                                        BACKEND_URL +
                                        attributes.media.data[0].attributes.url
                                      }`}
                                      width={80}
                                      height={80}
                                      objectFit="cover"
                                      className="rounded"
                                    />
                                  </div>
                                  <figcaption className="ml-3">
                                    <p className="text-gray-600">
                                      {attributes.name}
                                    </p>
                                    <p className="mt-1 font-semibold">
                                      {
                                        data.orders.data[orderIndex].attributes
                                          .details[productIndex].quantity
                                      }{" "}
                                      x ${attributes.price}
                                    </p>
                                  </figcaption>
                                </figure>
                              </Link>
                            )
                          )}
                        </div>
                      </article>
                    ))
                  ) : (
                    <EmptyState
                      title="You have not yet ordered"
                      subtitle="Choose some products to order"
                      image={EmptyOrder}
                      btnText="Go to shop"
                      btnText2="Go Home"
                      btnLink="/shop"
                      btnLink2="/"
                    />
                  )}
                </article>
              </main>
            </div>
          </div>
        </section>
      </div>
    );

}

export default index;

我在NextJs和GraphQl中都非常新颖,任何建议都非常感谢!

I am implementing authentication on nextjs strapi graphql and I want to redirect user once he registers or logins or theres is jwt token in cookies but when I login. its not redirecting using router.push method, I am also checking in other pages if user exist in cookies but use`Effect not working Here is my code example
System Information
4.1.11:
Macos:
Mysql:
14.17.00:
6.14.13:
1.22.19:

import { useContext, useEffect, useState } from "react";
import Image from "next/image";
import Link from "next/link";
import { useMutation } from "@apollo/client";
import { LOGIN_USER } from "../../gql/mutations";
import { userContext } from "../../context/wrapppers/UserWrapper";
import { setUserAction } from "../../context/actions/user-actions";
import { SIGN_IN } from "../../context/actions/action-types";

import { useRouter } from "next/router";

function login() {
  const router = useRouter();
  const { user, dispatchUser } = useContext(userContext);
  const [credentials, setCredentials] = useState({});

  useEffect(() => {
    if (user !== "" && user !== undefined) {
      router.push("/account");
    }
  }, []);

  const [loginUser, { loading, error, data }] = useMutation(LOGIN_USER);

  useEffect(() => {
    if (data) {
      dispatchUser(
        setUserAction(
          {
            token: data.login.jwt,
            username: data.login.user.username,
            id: data.login.user.id,
            email: data.login.user.email,
          },
          SIGN_IN
        )
      );
    }
  }, [data]);

  if (loading) return <h1>logging in...</h1>;
  if (error) return <h1>{error.message}</h1>;

  console.log("user from login page", user);

  const handleChange = (e) => {
    setCredentials({
      ...credentials,
      [e.target.name]: e.target.value,
    });
  };

  const handleLogin = (e) => {
    if (typeof window === "undefined") {
      return;
    }
    e.preventDefault();
    loginUser({
      variables: {
        input: credentials,
      },
    });
  };

  return (
    <div className="h-screen bg-slate-50 flex justify-center items-center w-full">
      {error && <div>{error.message}</div>}
      <form onSubmit={handleLogin}>
        <div className="bg-white px-10 py-8 rounded-xl w-screen shadow-md max-w-sm">
          <Image
            src={require("../../public/Img/logo.png")}
            height={50}
            objectFit="contain"
            className="h-14 mb-4 mx-auto"
            alt=""
          />
          <div className="space-y-4">
            <h1 className="text-center text-2xl font-semibold text-gray-600">
              Login
            </h1>
            <div>
              <label
                for="email"
                className="block mb-1 text-gray-600 font-semibold"
              >
                Email or Username
              </label>
              <input
                name="identifier"
                onChange={handleChange}
                type="text"
                required
                className="bg-indigo-50 px-4 py-2 outline-none rounded-md w-full"
              />
            </div>
            <div>
              <label
                for="password"
                className="block mb-1 text-gray-600 font-semibold"
              >
                Password
              </label>
              <input
                name="password"
                onChange={handleChange}
                type="text"
                required
                className="bg-indigo-50 px-4 py-2 outline-none rounded-md w-full"
              />
            </div>
          </div>
          <button
            type="submit"
            className="mt-4 w-full bg-yellow-500 font-semibold py-2 rounded-md  tracking-wide"
          >
            Login
          </button>
          <Link href="account/register">
            <h3 className="mt-2 cursor-pointer">Or Create an account</h3>
          </Link>
        </div>
      </form>
    </div>
  );
}

export default login;

function index() {
  const router = useRouter();
  const { user, dispatchUser } = useContext(userContext);

  const [getUserOrders, { loading, error, data }] = useLazyQuery(USER_ORDERS);
  useEffect(() => {
    if (user) {
      getUserOrders({
        variables: {
          filters: {
            user: {
              id: {
                eq: user.id,
              },
            },
            status: {
              ne: "rejected",
            },
          },
        },
      });
    } else {
      router.push("/account/login");
    }
  }, [user]);

  if (error) return <div>{error.message}</div>;
  if (loading) return <div>Loading ...</div>;

  const handleLogout = () => {
    router.push("/account/login");
    dispatchUser(setUserAction(user, SIGN_OUT));
  };


    return (
      <div>
        <section className="py-5 sm:py-7 bg-gray-100">
          <div className="container max-w-screen-xl mx-auto px-4">
            Home/Account
          </div>
        </section>

        <section className="py-10">
          <div className="container max-w-screen-xl mx-auto px-4">
            <div className="flex flex-col md:flex-row -mx-4">
              <aside className="md:w-1/3 lg:w-1/4 px-4">
                <ul>
                  <li>
                    <Link href="/account">
                      <span className="block px-3 py-2 text-primary bg-gray-100 hover:bg-orange-100  rounded-md">
                        Account
                      </span>
                    </Link>
                  </li>
                  <li>
                    <div
                      className="cursor-pointer flex items-center"
                      onClick={handleLogout}
                    >
                      <IoIosLogOut size="20" className="mr-2" />
                      <span>Log out</span>
                    </div>
                  </li>
                </ul>
              </aside>
              <main className="md:w-2/3 lg:w-3/4 px-4">
                <article className="border border-gray-200 bg-white shadow-sm rounded mb-5 p-3 lg:p-5">
                  <figure className="flex items-start sm:items-center">
                    <AiOutlineUser size="50" />
                    <figcaption>
                      <h5 className="font-semibold text-lg">
                        Hi {user.username}
                      </h5>
                      <p>Email: {user.email}</p>
                    </figcaption>
                  </figure>

                  <hr className="my-4" />

                  <h3 className="text-xl font-semibold mb-5">Order History</h3>

                  {data && data.orders.data.length !== 0 ? (
                    data.orders.data.map(({ id, attributes }, orderIndex) => (
                      <article
                        key={id}
                        className="p-3 lg:p-5 mb-5 bg-white border border-blue-600 rounded-md"
                      >
                        <header className="lg:flex justify-between mb-4">
                          <div className="mb-4 lg:mb-0">
                            <p className="font-semibold">
                              <span>Order ID: #{id} </span>
                              <span className="text-green-500">
                                {" "}
                                • {attributes.status}{" "}
                              </span>
                            </p>
                            <p className="text-gray-500">
                              {" "}
                              {new Date(
                                attributes.createdAt
                              ).toLocaleDateString()}
                            </p>
                          </div>
                        </header>

                        <hr className="my-4" />

                        <div className="grid md:grid-cols-2 lg:grid-cols-3 gap-2">
                          {attributes.products.data.map(
                            ({ id, attributes }, productIndex) => (
                              <Link href={`/shop/${attributes.slug}`}>
                                <figure
                                  key={id}
                                  className="flex flex-row mb-4 cursor-pointer"
                                >
                                  <div>
                                    <Image
                                      src={`${
                                        BACKEND_URL +
                                        attributes.media.data[0].attributes.url
                                      }`}
                                      width={80}
                                      height={80}
                                      objectFit="cover"
                                      className="rounded"
                                    />
                                  </div>
                                  <figcaption className="ml-3">
                                    <p className="text-gray-600">
                                      {attributes.name}
                                    </p>
                                    <p className="mt-1 font-semibold">
                                      {
                                        data.orders.data[orderIndex].attributes
                                          .details[productIndex].quantity
                                      }{" "}
                                      x ${attributes.price}
                                    </p>
                                  </figcaption>
                                </figure>
                              </Link>
                            )
                          )}
                        </div>
                      </article>
                    ))
                  ) : (
                    <EmptyState
                      title="You have not yet ordered"
                      subtitle="Choose some products to order"
                      image={EmptyOrder}
                      btnText="Go to shop"
                      btnText2="Go Home"
                      btnLink="/shop"
                      btnLink2="/"
                    />
                  )}
                </article>
              </main>
            </div>
          </div>
        </section>
      </div>
    );

}

export default index;

I am quite new in nextjs and graphql any suggesstion highly appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文