aww*_*ter 71 reactjs redux axios
我有一个react/redux应用程序从api服务器获取令牌.在用户进行身份验证之后,我想让所有axios请求都将该令牌作为Authorization标头,而不必手动将其附加到操作中的每个请求.我是新手反应/ 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() {
/* here is where I'd like the header to be attached automatically if the user
has logged in */
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:
// here is where I believe I should be attaching the header to all axios requests.
return {
token: action.payload.data.key,
isAuthenticated: true
};
case LOGOUT_USER:
// i would remove the header from all axios requests here.
return initialState;
default:
return state;
}
}
Run Code Online (Sandbox Code Playgroud)
我的令牌存储在redux store下state.session.token.
我对如何继续有点迷茫.我已经尝试在我的根目录中的文件中创建一个axios实例并更新/导入而不是从node_modules,但是当状态改变时它没有附加头.任何反馈/想法都非常感谢,谢谢.
Har*_*dha 104
从文档中axios可以看到有一种机制可供您设置默认标头,该标头将随您发出的每个请求一起发送.
// Add a request interceptor
axios.interceptors.request.use(function (config) {
const token = store.getState().session.token;
config.headers.Authorization = token;
return config;
});
Run Code Online (Sandbox Code Playgroud)
所以在你的情况下:
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
Run Code Online (Sandbox Code Playgroud)
如果需要,您可以创建一个自执行功能,当商店中存在令牌时,该功能将设置授权标头.
axios.defaults.headers.common['Authorization'] = store.getState().session.token;
Run Code Online (Sandbox Code Playgroud)
现在,您不再需要手动将令牌附加到每个请求.您可以将上述功能放在保证每次执行的文件中(例如:包含路径的文件).
希望能帮助到你 :)
Kma*_*hta 41
对我来说,最好的解决方案是创建一个客户端服务,您将使用它来实例化其令牌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);
Run Code Online (Sandbox Code Playgroud)
在此客户端中,您还可以根据需要从localStorage/cookie中检索令牌.
lli*_*oor 35
如果您使用"axios":"^ 0.17.1"版本,您可以这样做:
创建axios实例:
// Default config options
const defaultOptions = {
baseURL: <CHANGE-TO-URL>,
headers: {
'Content-Type': 'application/json',
},
};
// Create instance
let instance = axios.create(defaultOptions);
// Set the AUTH token for any request
instance.interceptors.request.use(function (config) {
const token = localStorage.getItem('token');
config.headers.Authorization = token ? `Bearer ${token}` : '';
return config;
});
Run Code Online (Sandbox Code Playgroud)
然后,对于任何请求,将从localStorage中选择令牌,并将其添加到请求标头中.
我使用此代码在整个应用程序中使用相同的实例:
import axios from 'axios';
const fetchClient = () => {
const defaultOptions = {
baseURL: process.env.REACT_APP_API_PATH,
method: 'get',
headers: {
'Content-Type': 'application/json',
},
};
// Create instance
let instance = axios.create(defaultOptions);
// Set the AUTH token for any request
instance.interceptors.request.use(function (config) {
const token = localStorage.getItem('token');
config.headers.Authorization = token ? `Bearer ${token}` : '';
return config;
});
return instance;
};
export default fetchClient();
Run Code Online (Sandbox Code Playgroud)
祝好运.
同样,我们有一个函数可以从以下调用中设置或删除令牌:
import axios from 'axios';
export default function setAuthToken(token) {
axios.defaults.headers.common['Authorization'] = '';
delete axios.defaults.headers.common['Authorization'];
if (token) {
axios.defaults.headers.common['Authorization'] = `${token}`;
}
}
Run Code Online (Sandbox Code Playgroud)
我们总是在初始化时清除现有令牌,然后建立接收到的令牌。
如果您想在将来调用其他 api 路由并将您的令牌保留在商店中,请尝试使用 redux middleware。
中间件可以侦听 api 操作并相应地通过 axios 分派 api 请求。
这是一个非常基本的例子:
动作/api.js
export const CALL_API = 'CALL_API';
function onSuccess(payload) {
return {
type: 'SUCCESS',
payload
};
}
function onError(payload) {
return {
type: 'ERROR',
payload,
error: true
};
}
export function apiLogin(credentials) {
return {
onSuccess,
onError,
type: CALL_API,
params: { ...credentials },
method: 'post',
url: 'login'
};
}
Run Code Online (Sandbox Code Playgroud)
中间件/api.js
import axios from 'axios';
import { CALL_API } from '../actions/api';
export default ({ getState, dispatch }) => next => async action => {
// Ignore anything that's not calling the api
if (action.type !== CALL_API) {
return next(action);
}
// Grab the token from state
const { token } = getState().session;
// Format the request and attach the token.
const { method, onSuccess, onError, params, url } = action;
const defaultOptions = {
headers: {
Authorization: token ? `Token ${token}` : '',
}
};
const options = {
...defaultOptions,
...params
};
try {
const response = await axios[method](url, options);
dispatch(onSuccess(response.data));
} catch (error) {
dispatch(onError(error.data));
}
return next(action);
};
Run Code Online (Sandbox Code Playgroud)
重点是为每个请求在拦截器上设置令牌
import axios from "axios";
const httpClient = axios.create({
baseURL: "http://youradress",
// baseURL: process.env.APP_API_BASE_URL,
});
httpClient.interceptors.request.use(function (config) {
const token = localStorage.getItem('token');
config.headers.Authorization = token ? `Bearer ${token}` : '';
return config;
});
Run Code Online (Sandbox Code Playgroud)