搜尋

首頁  >  問答  >  主體

如何保持我的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(() => {
    如果(用戶){
      警報(用戶)
    }
  }, []);
  返回 (
    <div className={styles.home}>
      <標題>
        <h3 className={ubuntu.className}>
          你好,<br />> {用戶?.用戶名}!
        </h3>
        <輸入類型=“文字”;佔位符=“搜尋” >>
      </標題>

      <div className={styles.nav}>
        

註解

<div className={styles.section}> <div className={styles.inner}> {/* {數據&& 資料.m​​ap((e) => ( <卡 原始資料={e} 顏色={顏色[Math.floor(Math.random() * color.length)]} >> ))} */}
); } 匯出預設首頁;</pre></p>
P粉744691205P粉744691205545 天前556

全部回覆(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
  • 取消回覆