从“next-auth”导入 NextAuth; 从“next-auth/providers/credentials”导入 CredentialsProvider; 从“axios”导入 axios; 导出默认 NextAuth({ 提供者:[ 凭证提供者({ 名称:“凭证”, 证书: { 用户名:{ 标签:“用户名”,类型:“文本”,占位符:“贾斯汀” }, 密码:{标签:“密码”,类型:“密码”,占位符:“******”}, }, 异步授权(凭据,请求){ const url = req.body.callbackUrl.split(“/auth”)[0]; const { 用户名,密码 } = 凭据; const 用户 = 等待 axios({ url: `${url}/api/user/login`, 方法:“POST”, 数据: { 用户名: 用户名, 密码: 密码, }, “内容类型”:“application/json”, }) .then((res) => { 返回res.data; }) .catch((错误) => { if (err.response.data) { 抛出新错误(err.response.data); } 别的 { 返回空值; } 返回空值; }); 返回用户; }, }), ], 回调:{ jwt: ({ 令牌, 用户 }) => { 如果(用户){ token.user = 用户; } 返回令牌; }, 会话:({会话,令牌})=> { 如果(令牌){ 会话.用户 = 令牌.用户; } 返回会话; }, }, 页数:{ 登录:“/auth/login”, 新用户:“/auth/register”, }, });</pre> <p>这是我的/home路由的感觉</p>从“@/components/card/Card”导入卡; 从“react”导入 React, { useEffect, useState }; 从“./home.module.css”导入样式; 从“@next/font/google”导入 { Ubuntu }; 从“next-auth/react”导入{useSession}; 从“react-redux”导入{useDispatch,useSelector}; const ubuntu = Ubuntu({ 权重: "500", 子集: ["西里尔文"] }); const getData = async (id) =>; { const res = 等待获取({ url: "http://localhost:3000/api/note/getall", 方法:“POST”, “内容类型”:“application/json”, 数据: { 身份证号: 身份证号, }, }); 如果(!res.ok){ 控制台.log(id); throw new Error(“无法获取”); } 别的 { 返回 res.json(); 控制台.log(res); } }; 函数主页(){ const 颜色 = [“#E9F5FC”、“#FFF5E1”、“#FFE9F3”、“#F3F5F7”]; const random = Math.floor(Math.random() * 5); const rc = 颜色[随机]; const [pop, setPop] = useState(“无”); const { user } = useSelector((state) => state.user); const getDataa = async () =>; { 控制台.log(用户) const data =等待 getData(user._id); 控制台.log(数据); }; useEffect(() => { 如果(用户){ 警报(用户) } }, []); 返回 (; <标题> <h3 className={ubuntu.className}> 你好,<br />> {用户?.用户名}! </h3> <输入类型=“文本”;占位符=“搜索” >> </标题> <div className={styles.nav}><div className={styles.section}> <div className={styles.inner}> {/* {数据&& 数据.map((e) => ( <卡 原始数据={e} 颜色={颜色[Math.floor(Math.random() * color.length)]} >> ))} */}注释
P粉4289867442023-08-26 13:25:30
这段代码似乎会创建一个问题/竞争条件,因为你混合了两种不同的异步Promise处理方式:
const user = await axios({ url: `${url}/api/user/login`, method: "POST", data: { username: username, password: password, }, "content-type": "application/json", }) .then((res) => { return res.data; }) .catch((err) => { if (err.response.data) { throw new Error(err.response.data); } else { return null; } return null; }); return user;
应该改成这样:
try { const user = await axios({ url: `${url}/api/user/login`, method: "POST", data: { username: username, password: password, }, "content-type": "application/json", }); return user.data; } catch (err) { if (err.response.data) { throw new Error(err.response.data); } else { return null; } }
或者这样:
axios({ url: `${url}/api/user/login`, method: "POST", data: { username: username, password: password, }, "content-type": "application/json", }).then((res) => { return res.data; }).catch((err) => { if (err.response.data) { throw new Error(err.response.data); } else { return null; } return null; });
P粉7072355682023-08-26 10:01:08
将此component
添加到您的App.js文件中:
function Auth({ children }) { const router = useRouter(); const { status } = useSession({ required: true, onUnauthenticated() { router.push("/sign-in"); }, }); if (status === "loading") { returnLoading ...; } return children; }
现在在您的App函数中,不再返回<Component {...pageProps} />
,而是首先检查component
是否具有auth
属性,所以您将其包装在<Auth>
中,以确保每个需要会话的组件只有在会话加载完成后才会挂载(这就是为什么用户为null
,因为会话仍在加载中)
{ Component.auth ? () : ( ); }
最后,您将.auth = {}
添加到您想要定义会话的每个页面中(在您的情况下是Home)
const Home = () => { //.... } Home.auth = {};
这还有助于在会话过期时将用户重定向到/sign-in
页面