NextJS重定向和更新更改不适用于Strapi Apollo GraphQl身份验证
我正在对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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论