平时做技术实践时,很多问题不是概念不会,而是细节没串起来。拿“ch@tGPT deBug解决管理员登入服务器返回401问题”来说,它看着像小点,放到项目里常会牵出环境、配置、兼容性和维护成本。下面按实际使用顺序,把思路、关键写法和容易踩坑的地方讲清楚,方便你直接对照操作。
连接浅包后,会调用函数,弹出窗口让用户签名
if (signatureMessage) {
await signMessageAsync({
message: signatureMessage,
});
dispatch(changeHasLoggedToTrue());
}
有了签名后,会调用signIn来设置本地存储
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);//设置本地存储
refreshAPIToken();
addressInfo.current.address = address;
} catch (err) {
console.log("signin");
showMessage({
type: "error",
title: "Failed to sign-in",
body: err.message,
});
disconnect();
}
};落到代码里,若用户连接了浅包就会调接口,拿到用户是否是管理员 借助RTK(redux toolkit)存储在isAdmin变量里
const res = await API.get(`/member/${address}`);
if (!res.data.data) {
dispatch(changeIsAdminToFalse());
return;
}
if (res.data.data.role.includes("Member")) {
dispatch(changeIsMemberToTrue());
}
当isAdmin为true的时候,才显示member列表
从实现思路看,后端接口也限制了,不是管理员拿不到数据,而我明明用管理员登入了,还是拿不到,刷新才拿得到数据。不刷新的时候控制台报401,Unauthorized,没有权限。
于是问了gpt
gpt给了5种可能的原因

理解这一步时,关键是第一条 问题定位到了没有accessToken 但是我一看控制台Application里面 access token没错,是有的,但是数据要刷新页面才出来,于是我继续问
我: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: 翻譯:刷新后才出现数据,可能是因为在发送请求的时候access token没有被发送,为了确保所有的请求都带有access token 需给axios实例设置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给了一段代码 我自己再看逻辑 修改 关键就是当服务器得到401的时候,要给axios请求设置accessToken,再次发送请求;
1.每次请求刚开始都得到401,request拦截之后,再次发送请求才拿到数据
2.如果accessToken过期了,请求不到数据,需求是要清除本地缓存同时退出浅包登录
在这个场景下,第2条是新增的需求,如何判断accessToken过期,GPT说如果accessToken过期,服务器会得到401,所以这里if判断服务器会得到401后的逻辑不能是重新发送请求。首先要解决第一个问题。为何每次请求都得到401?
结合项目来看,打log,发现在连接浅包set token,token有值之前,就发送请求,所以要在连接浅包set token,确保token有值之后才发送请求,之前是判断为管理员就发送请求,这个在需求层面来将没错,但是connect wallet 设置isAdmin为true的时候还没有set token 所以在 set token之后新增 dispatch(changeSigninToTrue()); useEffecthasSiginin:
useEffect(() => {
if (hasSiginin) {
console.log("有發送請求");
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;落到代码里,之后管理员连接浅包,就能拿到数据了,因为发送请求的时候 header里面有了Authorization,即有了accessToken
落到代码里,总的来说,ch@tGPT deBug登入401这部分内容适合结合实际项目边做边理解。先抓住核心思路,再逐步补上细节和边界处理,最后效果会更稳定,也更容易复用。