搜索

首页  >  问答  >  正文

如何保持我的next-auth用户会话并在其他路由中使用提供的ID获取数据?

<p>我想在这里实现的是,每当用户登录时,我希望存储返回的数据,因为数据中包含一个我将在其他路由中使用的ID来获取数据。当用户成功登录后,他将被重定向到/home路由,并且从会话中获取的ID将用于获取数据。一切都正常工作,但如果我刷新主页,用户将变为空。</p> <p>这是我的[...nextauth].js文件的样子。</p>
从“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)]} >> ))} */}
); } 导出默认主页;</pre></p>
P粉744691205P粉744691205446 天前496

全部回复(2)我来回复

  • P粉428986744

    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;
    });

    回复
    0
  • P粉707235568

    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") {
        return 
    Loading ...
    ; } return children; }

    现在在您的App函数中,不再返回<Component {...pageProps} />,而是首先检查component是否具有auth属性,所以您将其包装在<Auth>中,以确保每个需要会话的组件只有在会话加载完成后才会挂载(这就是为什么用户为null,因为会话仍在加载中)

    {
      Component.auth ? (
        
          
        
      ) : (
        
      );
    }
    
    

    最后,您将.auth = {}添加到您想要定义会话的每个页面中(在您的情况下是Home)

    const Home = () => {
    //....
    }
    Home.auth = {};
    

    这还有助于在会话过期时将用户重定向到/sign-in页面

    回复
    0
  • 取消回复