從「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}>註解
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
頁面