chatGPT?deBug解決管理員登入服務(wù)器返回401問題
問題復(fù)現(xiàn):
連接錢包后,會(huì)調(diào)用函數(shù),彈出窗口讓用戶簽名
if (signatureMessage) { await signMessageAsync({ message: signatureMessage, }); dispatch(changeHasLoggedToTrue()); }
有了簽名后,會(huì)調(diào)用signIn來設(shè)置本地存儲(chǔ)
signIn函數(shù)
const signIn = async (signature) => { try { const signinRes = await API.post(`/auth/signin`, { address: address, signature: signature, }); const accessToken = signinRes.data?.data?.access_token; setLocalStorage("accessToken", accessToken);//設(shè)置本地存儲(chǔ) refreshAPIToken(); addressInfo.current.address = address; } catch (err) { console.log("signin"); showMessage({ type: "error", title: "Failed to sign-in", body: err.message, }); disconnect(); } };
如果用戶連接了錢包就會(huì)調(diào)接口,獲取用戶是否是管理員 通過RTK(redux toolkit)存儲(chǔ)在isAdmin變量里
const res = await API.get(`/member/${address}`); if (!res.data.data) { dispatch(changeIsAdminToFalse()); return; } if (res.data.data.role.includes("Member")) { dispatch(changeIsMemberToTrue()); }
當(dāng)isAdmin為true的時(shí)候,才顯示member列表
后端接口也限制了,不是管理員拿不到數(shù)據(jù),而我明明用管理員登入了,還是拿不到,刷新才拿得到數(shù)據(jù)。不刷新的時(shí)候控制臺(tái)報(bào)401,Unauthorized,沒有權(quán)限。
解決過程
于是問了gpt
gpt給了5種可能的原因
關(guān)鍵是第一條 問題定位到了沒有accessToken 但是我一看控制臺(tái)Application里面 access token沒錯(cuò),是有的,但是數(shù)據(jù)要刷新頁(yè)面才出來,于是我繼續(xù)問
我:the access token is right , we can get the requested source by this token after refresh. But how to get the requested source without refresh
GPT:If you're able to access the resource after refreshing the page, it's possible that the access token is not being sent with subsequent requests after the initial connection is made.
To ensure that the access token is being sent with all subsequent requests, you can set the token in the headers of the Axios instance. Here's an example of how to do this: 翻譯:刷新后才出現(xiàn)數(shù)據(jù),可能是因?yàn)樵诎l(fā)送請(qǐng)求的時(shí)候access token沒有被發(fā)送,為了確保所有的請(qǐng)求都帶有access token 需要給axios實(shí)例設(shè)置header
import axios from 'axios'; const API = axios.create({ baseURL: 'https://example.com/api', headers: { Authorization: `Bearer ${getLocalStorage('accessToken')}`, }, }); API.interceptors.response.use( response => response, async error => { const originalRequest = error.config; if (error.response.status === 401 && !originalRequest._retry) { originalRequest._retry = true; const accessToken = await handleRefreshToken(); API.defaults.headers.common.Authorization = `Bearer ${accessToken}`; return API(originalRequest); } return Promise.reject(error); }, );
GPT給了一段代碼 我自己再看邏輯 修改 關(guān)鍵就是當(dāng)服務(wù)器返回401的時(shí)候,要給axios請(qǐng)求設(shè)置accessToken,再次發(fā)送請(qǐng)求;
漏洞
1.每次請(qǐng)求剛開始都返回401,request攔截之后,再次發(fā)送請(qǐng)求才拿到數(shù)據(jù)
2.如果accessToken過期了,請(qǐng)求不到數(shù)據(jù),需求是要清除本地緩存并退出錢包登錄
第2條是新增的需求,如何判斷accessToken過期,GPT說如果accessToken過期,服務(wù)器會(huì)返回401,所以這里if判斷服務(wù)器會(huì)返回401后的邏輯不能是重新發(fā)送請(qǐng)求。首先要解決第一個(gè)問題。為何每次請(qǐng)求都返回401?
打log,發(fā)現(xiàn)在連接錢包set token,token有值之前,就發(fā)送請(qǐng)求,所以要在連接錢包set token,確保token有值之后才發(fā)送請(qǐng)求,之前是判斷為管理員就發(fā)送請(qǐng)求,這個(gè)在需求層面來將沒錯(cuò),但是connect wallet 設(shè)置isAdmin為true的時(shí)候還沒有set token 所以在 set token之后新增 dispatch(changeSigninToTrue());
useEffect監(jiān)聽hasSiginin:
useEffect(() => { if (hasSiginin) { console.log("有發(fā)送請(qǐng)求"); searchList(); } }, []);
最終代碼
import axios from "axios"; import { getLocalStorage, removeLocalStorage } from "@/src/utils/utility"; import { useLogout } from "../src/hooks/useLogout"; const API = axios.create({ baseURL: process.env.NEXT_PUBLIC_FRENART_BACKEND_API, }); API.interceptors.request.use( (config) => { const accessToken = refreshAPIToken(); if (accessToken) { config.headers.Authorization = `Bearer ${accessToken}`; //accessToken } return config; }, (error) => Promise.reject(error) ); function handleUnauthorizedError() { const logout = useLogout(); logout(); } API.interceptors.response.use( (response) => response, async (error) => { const accessToken = refreshAPIToken(); error.config.headers.Authorization = `Bearer ${accessToken}`; const originalRequest = error.config; if (error.response?.status === 401 && !originalRequest._retry) { console.log("401"); handleUnauthorizedError(); } return Promise.reject(error); } ); function refreshAPIToken() { const accessToken = getLocalStorage("accessToken"); API.defaults.headers.common.Authorization = `Bearer ${accessToken}`; return accessToken; } export { refreshAPIToken }; export default API;
之后管理員連接錢包,就能拿到數(shù)據(jù)了,因?yàn)榘l(fā)送請(qǐng)求的時(shí)候 header里面有了Authorization,即有了accessToken
以上就是chatGPT deBug解決管理員登入,服務(wù)器返回401,沒有拿到數(shù)據(jù)的詳細(xì)內(nèi)容,更多關(guān)于chatGPT deBug解決管理員登入,服務(wù)器返回401,沒有拿到數(shù)據(jù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
網(wǎng)址(URL)支持的最大長(zhǎng)度是多少?最大支持多少個(gè)字符?
這篇文章主要介紹了網(wǎng)址(URL)支持的最大長(zhǎng)度是多少?最大支持多少個(gè)字符?本文總結(jié)了IIS、apache服務(wù)器及瀏覽器軟件Internet Explorer、Firefox、Opera、chrome等主流的瀏覽器軟件支持情況,需要的朋友可以參考下2015-07-07國(guó)外開發(fā)者談為何放棄PHP而改用Python
本文作者作為一名從事PHP開發(fā)11年的資深開發(fā)者,卻放棄了PHP而改用Python。2009-09-09Grafana?系列之統(tǒng)一展示Prometheus數(shù)據(jù)源
這篇文章主要為大家介紹了Grafana?系列之統(tǒng)一展示Prometheus數(shù)據(jù)源配置詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05Source?Insight?4.0.093?安裝破解詳細(xì)圖文教程
這篇文章主要介紹了Source?Insight?4.0.093?安裝破解詳細(xì)圖文教程,source?insight?4是一款非常強(qiáng)大的程序編輯器,如果你沒有一款合適的代碼編輯器,那么這款軟件不妨試試,可能你會(huì)喜歡2022-08-08