如何保持我的next-auth用戶會話並在其他路由中使用提供的ID獲取資料?
P粉744691205
P粉744691205 2023-08-25 15:35:57
0
2
491
<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>
2
0
0
P粉744691205
P粉744691205

全部回覆(2)
P粉428986744

這段程式碼似乎會創造一個問題/競爭條件,因為你混合了兩種不同的非同步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粉707235568

將此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頁面

熱門專題
更多>
熱門文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!