chatGPT deBug解决管理员登入服务器返回401问题
作者:boombb 发布时间:2022-08-07 06:38:09
问题复现:
连接钱包后,会调用函数,弹出窗口让用户签名
if (signatureMessage) {
await signMessageAsync({
message: signatureMessage,
});
dispatch(changeHasLoggedToTrue());
}
有了签名后,会调用signIn来设置本地存储
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());
useEffect监听hasSiginin:
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
来源:https://juejin.cn/post/7229528526402977829


猜你喜欢
- classList属性的方法:add();remove();toggle();描述,在一些页面我们需要使用两个按钮来回切换,如图:我们要使用
- 建立完回归模型后,还需要验证咱们建立的模型是否合适,换句话说,就是咱们建立的模型是否真的能代表现有的因变量与自变量关系,这个验证标准一般就选
- Python的环境变量环境变量说明PYTHONSTARTUP在交互式启动时执行的文件(无默认值)PYTHONPATH‘:' - 以默
- 今天来和大家聊聊抽样的几种常用方法,以及在Python中是如何实现的。抽样是统计学、机器学习中非常重要,也是经常用到的方法,因为大多时候使用
- 前言最近碰到了照片识别的场景,正好使用了face_recognition项目,给大家分享分享。face_recognition项目能做的很多
- 本文实例讲述了php实现的三个常用加密解密功能函数。分享给大家供大家参考,具体如下:算法一://加密函数function lock_url(
- Harris 角点检测算法1. 角点角点是水平方向、垂直方向变化都很大的像素。角点检测算法的基本思想:
- 本文介绍一个用python结合xlsxwriter自动生成业务报表的程序。这里的业务数据采用的是指定的值,真实情况下需要其他程序来接入数据。
- 它解析并马上执行动态的SQL语句或非运行时创建的PL/SQL块.动态创建和执行SQL语句性能超前,EXECUTE IMMEDIATE的目标在
- PyTorch基础入门二:PyTorch搭建一维线性回归模型1)一维线性回归模型的理论基础给定数据集,线性回归希望能够优化出一个好的函数,使
- 这篇文章主要介绍了Python读取csv文件实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友
- 最近央视新闻记者王冰冰以清除可爱和专业的新闻业务水平深受众多网友喜爱,b站也有很多up主剪辑了关于王冰冰的视频。我们都是知道b站是一个弹幕网
- 通配符:通配符描述示例%包含零个或更多字符的任意字符串。WHERE title LIKE '%computer%' 将查找处
- 在上篇博客中,我们已经实现了水平投影和垂直投影图的绘制。接下来,我们可以根据获得的投影数据进行图像的分割,该法用于文本分割较多,所以此处依然
- 因为编写了一个Python程序,密集的操作了一个Mysql库,之前数据量不大时,没发现很慢,后来越来越慢,以为只是数据量大了的原因,但是后来
- python使用folium 库生成地图网页的具体代码,供大家参考,具体内容如下folium 官网import foliumimport p
- 本文实例为大家分享了微信小程序无滑动效果的tab点击切换的具体代码,供大家参考,具体内容如下<!--pages/dingdan/din
- 题目描述原题链接 :35. 搜索插入位置 - 力扣(LeetCode) (leetcode-cn.com)给定一个排序数组和一个目标值,在数
- 效果图:代码如下:<!DOCTYPE html><html><head> <meta charse
- <html> 题:<br /> 有n个直线最多可以把一个平面分成多少个部分<br /><br /&