我在Login组件中设置axios.defaults.headers.Authorization = MY_TOKEN,该组件在Authentication组件中呈现,该组件检查this.state.loggedin是否设置为true。如果为false,则呈现Login组件;如果为true,则使用BrowserRouter呈现UserComponent。 BrowserRouter读取“ /”路径并导航到Documents组件。在此导航页面期间,刷新并清除axios.defaults.headers.Authorization,返回未定义的值。即使刷新页面,如何保存axios.defaults.headers?还是应该在路由器每次导航到其他组件时初始化默认标头?
更新
添加了一些代码,如何在Authentication.js中呈现
render() {
return (
<UserNavigationContainer
{...this.props}
logout={this.onClickLogoutHandler}
/>
);
}
UserNavigationContainer.js渲染溃败(代码不完整)
<BrowserRouter>
<div>
<UserNavigationComponent {...this.props}>
<Switch>
<Route
exact
path="/"
component={UserSubmittedDocumentsContainer}
/>
实际上,当呈现UserNavigationContainer时,它导航到“ /”并在导航时刷新页面。
答案 0 :(得分:1)
我也有类似的经历,这就是我能够解决的方法
在用户登录/注册后将令牌保留在本地存储中: 第一步是在登录/注册成功后将用户令牌保留在本地存储中,您可以在浏览器的本地存储API here
上进行读取移动将“授权标头”设置为始终呈现而不考虑当前路径的组件的逻辑(在我的情况下为导航栏组件): 接下来是将负责设置Authorization标头的逻辑移到我的导航栏组件中,这样做,它会自动从本地存储中获取活动用户的令牌并设置授权标头。现在,无论react-router呈现的组件是什么,都将不断设置授权标头,从而避免了其他每个组件都需要这样做。
PS :移动逻辑并不会阻止您最初在登录组件内部设置授权标头,它仅解决了对要渲染的每个其他组件这样做的问题。
答案 1 :(得分:1)
我遇到了同样的问题。我通过在根文件中设置请求通用标头解决了我的问题。就我而言,它是index.js。
您是否注意到我正在从localStorage设置app_token?
最初,AuthLayout呈现登录组件。如果登录成功,我必须重定向到管理路由。
Auth.js
因此,我计划在登录组件中设置标题。如果登录成功,我可以在请求标头中设置app_token。一切顺利,直到我刷新页面。
Login.js
因此,我在localStorage中设置了令牌,并在index.js中使用了它来全局设置标头。
Login.js
我想这不是更好的解决方案。好吧,即使页面刷新后,我也可以全局设置标题并使用令牌进行身份验证。
更新:
在标头中设置授权的另一种简单解决方案是使用拦截器。
第1步:创建一个名为interceptor.js的文件。创建一个实例。
const axios = require("axios");
const axiosApiInstance = axios.create();
// Request interceptor for API calls
axiosApiInstance.interceptors.request.use(
async (config) => {
config.headers = {
Authorization: `Bearer ${localStorage.getItem("token")}`,
};
return config;
},
(error) => {
Promise.reject(error);
}
);
export default axiosApiInstance;
第2步:调用需要授权标头的后续API,如下所述。
import axiosApiInstance from "./interceptor";
let response = await axiosApiInstance.get(
"/api/***"
);
return response;
谢谢
答案 2 :(得分:0)
达马利的答案很正确,但我也认为值得对此进行扩展:
移动将Authorization标头设置为始终存在的组件的逻辑 不管当前路径如何渲染
说实话,很难理解OP的项目结构,因为出于某种原因发布的摘录与auth-routing逻辑有关,这不是要问的问题。但是,为清楚起见,请详细说明以上引用:
所有身份验证逻辑,包括设置axios标头,都应封装在单个组件中(可能是React Context)。它不像“设置标题并传递go”那样简单:任何生产级应用程序都需要:
这是身份验证模块的角色。
auth模块应控制axios身份验证标头。这意味着我们几乎可以肯定地说的是两个单独的模块:
现在:正如OP所观察到的或多或少:如果auth模块只是调用axios实例并在登录时对其应用标头,则刷新后将不会持续。
Damali答案的麻烦在于即使始终渲染您的身份验证模块(例如,它位于应用程序的顶部),axios配置仍然无法在页面刷新时保持不变。页面刷新将强制重新渲染:标题将消失。
答案看似简单:每次需要身份验证时(以及登录时)重新应用标头。有很多方法可以做到这一点,这里仅是一种:
// apiService.js
import Axios from 'axios';
const axios = Axios.create();
export function setDefaultHeader(key, value){
axios.defaults.headers.common[key] = value;
}
export axios;
// auth.js
import { axios, setDefaultHeader } from '../services/apiService.js';
const tokenKey = 'x-auth-token';
setDefaultHeader(tokenKey, localStorage[tokenKey]);