Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用React上下文正确设置Axios拦截器?_Javascript_Reactjs_Axios_Jwt_Jwt Auth - Fatal编程技术网

Javascript 如何使用React上下文正确设置Axios拦截器?

Javascript 如何使用React上下文正确设置Axios拦截器?,javascript,reactjs,axios,jwt,jwt-auth,Javascript,Reactjs,Axios,Jwt,Jwt Auth,因为我想用React上下文设置Axios拦截器,唯一可行的解决方案是创建拦截器组件,以便使用useContext钩子访问上下文状态和调度 问题是,这会创建一个闭包,并在调用拦截器时将旧数据返回给拦截器 我使用React/Node使用JWT身份验证,并使用上下文API存储访问令牌 这就是我的拦截器组件现在的样子: import React,{useffect,useContext}来自“React”; 从“../../components/Store/Store”导入{Context}; 从're

因为我想用React上下文设置Axios拦截器,唯一可行的解决方案是创建拦截器组件,以便使用useContext钩子访问上下文状态和调度

问题是,这会创建一个闭包,并在调用拦截器时将旧数据返回给拦截器

我使用React/Node使用JWT身份验证,并使用上下文API存储访问令牌

这就是我的拦截器组件现在的样子:

import React,{useffect,useContext}来自“React”;
从“../../components/Store/Store”导入{Context};
从'react router dom'导入{useHistory};
从“axios”导入axios;
const ax=axios.create();
常量拦截器=({children})=>{
const[store,dispatch]=useContext(上下文);
const history=useHistory();
const getRefreshToken=async()=>{
试一试{
如果(!store.user.token){
派遣({
键入:“setMain”,
加载:false,
错误:false,
auth:store.main.auth,
品牌:store.main.brand,
主题:store.main.theme,
});
const{data}=wait axios.post('/api/auth/refresh_-token'{
标题:{
凭据:“包括”,
},
});
if(data.user){
派遣({
类型:“设置存储”,
加载:false,
错误:false,
auth:store.main.auth,
品牌:store.main.brand,
主题:store.main.theme,
对,,
令牌:data.accessToken,
id:data.user.id,
名称:data.user.name,
电子邮件:data.user.email,
照片:data.user.photo,
stripeId:data.user.stripeId,
国家:data.user.country,
信息:{
项目:[],
计数:data.user.messages,
},
通知:
store.user.notifications.items.length!==data.user.notifications
? {
…store.user.notifications,
项目:[],
计数:data.user.notifications,
哈斯莫尔:没错,
光标:0,
上限:10,
}
: {
…store.user.notifications,
计数:data.user.notifications,
},
保存:数据。用户。保存。减少(函数(对象,项){
对象[项]=真;
返回对象;
}, {}),
购物车:{
条目:data.user.cart.reduce(函数(对象,条目){
对象[项目.艺术品]=真;
返回对象;
}, {}),
计数:Object.keys(data.user.cart).length,
},
});
}否则{
派遣({
键入:“setMain”,
加载:false,
错误:false,
auth:store.main.auth,
品牌:store.main.brand,
主题:store.main.theme,
});
}
}
}捕捉(错误){
派遣({
键入:“setMain”,
加载:false,
错误:正确,
auth:store.main.auth,
品牌:store.main.brand,
主题:store.main.theme,
});
}
};
const interceptTraffic=()=>{
ax.interceptors.request.use(
(请求)=>{
request.headers.Authorization=store.user.token
?`Bearer${store.user.token}`
: '';
返回请求;
},
(错误)=>{
返回承诺。拒绝(错误);
}
);
ax.interceptors.response.use(
(回应)=>{
返回响应;
},
异步(错误)=>{
console.log(错误);
if(error.response.status!==401){
返回新承诺((解决、拒绝)=>{
拒绝(错误);
});
}
如果(
error.config.url=='/api/auth/refresh\u令牌'||
error.response.message===“禁止”
) {
const{data}=await ax.post('/api/auth/logout'{
标题:{
凭据:“包括”,
},
});
派遣({
键入:“resetUser”,
});
history.push('/login');
返回新承诺((解决、拒绝)=>{
拒绝(错误);
});
}
const{data}=wait axios.post(`/api/auth/refresh\u-token`{
标题:{
凭据:“包括”,
},
});
派遣({
键入:“updateUser”,
令牌:data.accessToken,
电子邮件:data.user.email,
照片:data.user.photo,
stripeId:data.user.stripeId,
国家:data.user.country,
消息:{items:[],count:data.user.messages},
通知:
store.user.notifications.items.length!==data.user.notifications
? {
…store.user.notifications,
项目:[],
计数:data.user.notifications,
哈斯莫尔:没错,
光标:0,
上限:10,
}
: {
…store.user.notifications,
计数:data.user.notifications,
},
已保存:data.user.saved,
购物车:{items:{},计数:data.user.cart},
});
const config=error.config;
config.headers['Authorization']='Bearer${data.accessToken}`;
返回新承诺((解决、拒绝)=>{
axios
.request(配置)
。然后((响应)=>{
决心(回应);
})
localStorage.setItem('token', 'your_jwt_eykdfjkdf...');
import axios from 'axios';

// axios instance for making requests 
const axiosInstance = axios.create();

// request interceptor for adding token
axiosInstance.interceptors.request.use((config) => {
  // add token to request headers
  config.headers['Authorization'] = localStorage.getItem('token');
  return config;
});

export default axiosInstance;

import axios from './custom-axios';

axios.get('/url');
axios.post('/url', { message: 'hello' });
import axios from 'axios';

const customAxios = (token) => {
  // axios instance for making requests
  const axiosInstance = axios.create();

  // request interceptor for adding token
  axiosInstance.interceptors.request.use((config) => {
    // add token to request headers
    config.headers['Authorization'] = token;
    return config;
  });

  return axiosInstance;
};

export default customAxios;

import axios from './custom-axios';

// logic to get token from state (it may vary from your approach but the idea is same)
const token = useSelector(token => token);

axios(token).get('/url');
axios(token).post('/url', { message: 'hello' });
import axios from "axios";
import { ResetTokenAndReattemptRequest } from "domain/auth/AuthService";
    
export const api = axios.create({
    baseURL: process.env.REACT_APP_API_URL,
    headers: {
        "Content-Type": "application/json",
    },
});

export const apiSecure = axios.create({
    baseURL: process.env.REACT_APP_API_URL,
    headers: {
        Authorization: "Bearer " + localStorage.getItem("Token"),
        "Content-Type": "application/json",
    },
    
    export default api;
    
    apiSecure.interceptors.response.use(
        function (response) {
            return response;
        },
        function (error) {
            const access_token = localStorage.getItem("Token");
            if (error.response.status === 401 && access_token) {
                return ResetTokenAndReattemptRequest(error);
            } else {
                console.error(error);
            }
            return Promise.reject(error);
        }
    );
import api from "../api";
import axios from "axios";

let isAlreadyFetchingAccessToken = false;

let subscribers = [];

export async function ResetTokenAndReattemptRequest(error) {
  try {
    const { response: errorResponse } = error;
    const retryOriginalRequest = new Promise((resolve) => {
      addSubscriber((access_token) => {
        errorResponse.config.headers.Authorization = "Bearer " + access_token;
        resolve(axios(errorResponse.config));
      });
    });
    if (!isAlreadyFetchingAccessToken) {
      isAlreadyFetchingAccessToken = true;
      await api
        .post("/Auth/refresh", {
          Token: localStorage.getItem("RefreshToken"),
          LoginProvider: "Web",
        })
        .then(function (response) {
          localStorage.setItem("Token", response.data.accessToken);
          localStorage.setItem("RefreshToken", response.data.refreshToken);
          localStorage.setItem("ExpiresAt", response.data.expiresAt);
        })
        .catch(function (error) {
          return Promise.reject(error);
        });
      isAlreadyFetchingAccessToken = false;
      onAccessTokenFetched(localStorage.getItem("Token"));
    }
    return retryOriginalRequest;
  } catch (err) {
    return Promise.reject(err);
  }
}

function onAccessTokenFetched(access_token) {
  subscribers.forEach((callback) => callback(access_token));
  subscribers = [];
}

function addSubscriber(callback) {
  subscribers.push(callback);
}