如何在axios中全局设置身份验证令牌?
如何在axios中全局设置身份验证令牌?
我有一个使用React/Redux的应用程序,它从API服务器获取一个令牌。在用户验证之后,我希望所有的axios请求都将该令牌作为Authorization头部自动附加,而不需要手动将其附加到每个action的请求中。我对React/Redux还不太熟悉,对于最佳方法并没有找到什么有价值的信息。
这是我的Redux设置:
// actions.js import axios from 'axios'; export function loginUser(props) { const url = `https://api.mydomain.com/login/`; const { email, password } = props; const request = axios.post(url, { email, password }); return { type: LOGIN_USER, payload: request }; } export function fetchPages() { /* 这是我希望在用户登录后自动附加头部的地方 */ const request = axios.get(PAGES_URL); return { type: FETCH_PAGES, payload: request }; } // reducers.js const initialState = { isAuthenticated: false, token: null }; export default (state = initialState, action) => { switch(action.type) { case LOGIN_USER: /* 这是我认为应该在所有axios请求中附加头部的地方 */ return { token: action.payload.data.key, isAuthenticated: true }; case LOGOUT_USER: /* 我会在这里从所有axios请求中移除头部 */ return initialState; default: return state; } }
我的令牌存储在Redux存储的`state.session.token`下。
我有点迷失在如何继续下去。我尝试在我的根目录中创建一个axios实例的文件,并更新/导入它,而不是从node_modules中导入,但当状态发生变化时,它并没有附加头部。非常感谢任何反馈/想法。
如何在axios中全局设置授权令牌?
有多种方法可以实现这个目标。下面,我将解释两种最常见的方法。
1. 您可以使用axios拦截器来拦截任何请求并添加授权头。
// 添加请求拦截器 axios.interceptors.request.use(function (config) { const token = store.getState().session.token; config.headers.Authorization = token; return config; });
2. 在axios的文档中,您可以看到有一种机制可以设置默认头,这将在您发出的每个请求中发送。
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
因此,在您的情况下:
axios.defaults.headers.common['Authorization'] = store.getState().session.token;
如果您愿意,您可以创建一个自执行函数,当存储中存在令牌时,它将自动设置授权头。
(function() { String token = store.getState().session.token; if (token) { axios.defaults.headers.common['Authorization'] = token; } else { axios.defaults.headers.common['Authorization'] = null; /*如果设置null无法删除`Authorization`头,则尝试删除axios.defaults.headers.common['Authorization'];*/ } })();
现在,您不再需要手动附加令牌到每个请求中。您可以将上述函数放在每次执行时都会执行的文件中(例如:包含路由的文件)。
已经在使用redux-persist,但是将查看中间件以附加令牌到头部,谢谢!
您不需要中间件来将令牌附加到头部。将令牌附加到头部就像这样简单:`axios.defaults.header.common[Auth_Token] = token`。
我很好奇如何使用Fetch API实现这一点。
我相信,您需要编写一个覆盖fetch API的包装器来实现相同的功能。对于OP提出的问题,详细的答案超出了问题的范围。您可以提出另一个问题 :)
嗨,如果我使用默认头部来设置令牌,当我想要更新令牌时,它无法再次设置到头部。这样正确吗?所以我必须使用拦截器。
您可能需要添加`config.headers.Authorization = Bearer ${token}`。
您可能对github.com/developit/redaxios感兴趣。它是对fetch API的包装器。API与Axios类似。
如何使用Hooks设置这一行?`axios.defaults.headers.common['Authorization'] = store.getState().session.token;`
小提示:如果您按照第二种方法进行操作,则必须为应用程序中的每个Axios实例单独设置默认头部。这个问题让我花了一些时间才弄明白。
`store.getState()`是什么?这是您的redux存储吗?您不将令牌存储在cookie中吗?
由于某种原因,第二种方法不起作用:( 但是第一种方法可以。顺便感谢您提供的解决方案 🙂
我很好奇。在进行API调用(例如使用axios)时,您通常如何处理调用公共和私有端点(带/不带jwt授权标头)?是使用两个axios实例,一个处理令牌生命周期,另一个不处理吗?
为了避免为每个axios实例都这样做,您可以在登录逻辑中执行此操作。
问题出现的原因是想要在axios中全局设置认证令牌。为了解决这个问题,可以创建一个客户端服务,用于包装axios,并在实例化时传入令牌。
代码示例:
import axios from 'axios'; const client = (token = null) => { const defaultOptions = { headers: { Authorization: token ? `Token ${token}` : '', }, }; return { get: (url, options = {}) => axios.get(url, { ...defaultOptions, ...options }), post: (url, data, options = {}) => axios.post(url, data, { ...defaultOptions, ...options }), put: (url, data, options = {}) => axios.put(url, data, { ...defaultOptions, ...options }), delete: (url, options = {}) => axios.delete(url, { ...defaultOptions, ...options }), }; }; const request = client('MY SECRET TOKEN'); request.get(PAGES_URL);
这个客户端还可以从localStorage或cookie中获取令牌。
如果想要在request.get()中添加"application-type"头部,你的方法会覆盖defaultOptions中的头部。正确吗?谢谢。
问题原因:用户想要在axios中设置全局的auth token,以便在每个请求的请求头中添加该token。用户提供了一个使用axios创建实例的代码示例,并在其中使用interceptors来实现此功能。
解决方法:用户创建了一个名为fetchClient的函数,该函数返回一个axios实例。在这个函数中,用户使用interceptors来设置请求头中的token。在每个请求中,token会从localStorage中获取,并以Bearer Token的形式添加到请求头中。
然后,用户使用这个实例在整个应用程序中发送请求。
用户通过在axios实例中使用interceptors来设置全局auth token,以便在每个请求的请求头中添加该token。通过将token存储在localStorage中,并在每个请求中从localStorage中获取token并添加到请求头中,用户可以实现此功能。