我使用javascript和next-js中的magic登录将用户添加到我的应用程序中,它运行得很好,但我遇到的问题是。当用户重新登录页面时,我必须手动刷新页面以获取数据。我尝试过检查url参数,如果存在,则重新加载,然后更改更改url,使其没有url参数,这样它就不会循环。
但在点击magic login发送的电子邮件中的登录按钮后,路由器甚至没有找到。
import Head from "next/head";
import Image from "next/image";
import styles from "../styles/Home.module.css";
import { gql, useQuery } from "@apollo/client";
import useSWR from "swr";
import { useEffect } from "react";
import Layout from "../components/layout";
import { useRouter } from "next/router";
export const GET_DAD_HAT = gql`
query FindUserByID($id: ID!) {
findUserByID(id: $id) {
_id
hats {
data {
name
}
}
}
}
`;
const fetcher = (url) => fetch(url).then((r) => r.json());
function useAuth() {
const { data: user, error, mutate } = useSWR("/api/user", fetcher);
const loading = user?.token === false || user === undefined;
return {
user,
loading,
error,
};
}
export default function Profile() {
const { user, loading } = useAuth();
const router = useRouter();
useEffect(() => {
console.log("window", window);
console.log(Object.keys(router.query)[0]);
if (Object.keys(router.query)[0] === "magic_credentials") {
router.reload(window.location.pathname);
window.history.pushState({}, document.title, "/" + "profile");
}
if (loading) {
}
}, []);
return (
<Layout>
<main>{loading ? "Loading..." : <Data user={user} />}</main>
</Layout>
);
}
const Data = ({ user }) => {
const { loading, error, data } = useQuery(GET_DAD_HAT, {
variables: { id: user.id },
});
if (loading) return <h1>Loading...</h1>;
if (error) return <h1>{error.message}</h1>;
return <pre>{JSON.stringify(data, null, 2)}</pre>;
};
发生的情况是,在从电子邮件登录流重定向到应用程序后,数据一直停留在加载中,直到我手动点击刷新。
更新:我做了一个可复制的沙盒。https://omg5u.sse.codesandbox.io/login-magic
输入您的电子邮件,单击发送到电子邮件的登录链接。
随意使用一次性电子邮件服务,如https://getnada.com/如果没有阻止
当您到达配置文件页面时,看到它只是在加载,直到您点击刷新,它应该显示您的用户id和一个空的数据数组。
更新:当我第一次登录页面时,在获取到用户api路由中对fauna_client的cookie查找似乎返回了未定义的结果。但是,刷新后会返回cookie。如果我在点击刷新之前检查cookie是否存在,但如果我在终端中查找下一个,则在查找cookie之后会创建cookie。我认为这与登录api路由中的Magic重定向有关,在Magic登录后创建cookie。
还是很困惑。
必须在auth-verify页面和登录验证api路由上执行以下操作
useEffect(() => {
finishEmailRedirectLogin();
}, [router.query]);
const finishEmailRedirectLogin = () => {
if (router.query.magic_credential)
magicClient.auth
.loginWithCredential()
.then((didToken) => authenticateWithServer(didToken));
};
// Send token to server to validate
const authenticateWithServer = async (didToken) => {
let res = await fetch("/api/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + didToken,
},
});
if (res.status === 200) {
// Set the UserContext to the now logged in user
let userMetadata = await magicClient.user.getMetadata();
// await setUser(userMetadata);
router.push("/profile");
}
};
import { Magic } from "@magic-sdk/admin";
// Initiating Magic instance for server-side methods
const magic = new Magic(process.env.MAGIC_SECRET_KEY);
export default async function login(req, res) {
try {
const didToken = req.headers.authorization.substr(7);
await magic.token.validate(didToken);
res.status(200).json({ authenticated: true });
} catch (error) {
res.status(500).json({ error: error.message });
}
}