localStorage 项目未在 axios 中更新 headers
localStorage item not updating in axios headers
我正在使用 JWT 令牌身份验证系统,当我登录时,我得到了这样的令牌:
axios.post('/login', data)
.then(response => {
localStorage.setItem('token', response.data.token);
});
这很好用,令牌保存在 localStorage 中。但是,令牌不包含在以后的请求中。 授权 header 是 Bearer null
。
这就是我设置全局 axios 的方式 object。
window.axios = axios.create({
baseURL: '/api/',
timeout: 10000,
headers: {
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-TOKEN': document.head.querySelector('meta[name="csrf-token"]').content,
'Authorization': 'Bearer ' + localStorage.getItem('token')
}
});
如果我刷新站点,令牌 已设置,并且可以正确使用。
编辑:
我通过从 create()
方法中删除 Authorization
header 并使用 window.axios.defaults.headers.common['Authorization']
来让它工作。但是现在Laravel Echo出现了同样的问题。我这样创建实例:
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'xxx',
cluster: 'eu',
encrypted: true,
namespace: 'xxx',
auth: {
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token')
}
}
});
我这样更新 header:
window.setAuthToken = (token) => {
window.axios.defaults.headers.Authorization = 'Bearer ' + token;
window.Echo.options.auth.headers.Authorization = 'Bearer ' + token;
localStorage.setItem('token', token);
}
axios header更新成功,但Echo未更新
问题是您在页面加载时使用了 localStorage.getItem('token')
。当你在 localStorage
中设置它时,你必须在 axios header.
中更新它
window.axios = axios.create({
baseURL: '/api/',
timeout: 10000,
headers: {
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-TOKEN': document.head.querySelector('meta[name="csrf-token"]').content,
'Authorization': 'Bearer ' + localStorage.getItem('token')
}
});
axios.post('/login', data)
.then(response => {
localStorage.setItem('token', response.data.token);
window.axios.defaults.headers.common['Authorization'] = 'Bearer ' + localStorage.getItem('token');
});
为此使用 axios interceptors。每次请求调用都会运行。
最好将 axios 方法保存在单独的文件中并调用它,而不是直接在所有组件中使用它。这样,如果我们愿意,我们可以用最小的努力用另一个库替换 axios 。这是我在我的项目中所做的。
import axios from "axios";
import AuthService from "./auth";
import config from '../config'
const instance = axios.create({
baseURL: config.apiServer.url,
timeout: config.apiServer.timeout
});
instance.interceptors.request.use(
config => {
const token = AuthService.getToken();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
error => Promise.reject(error)
);
const ApiService = {
get(url) {
return instance.get(url)
.then(res => res)
.catch(reason => Promise.reject(reason));
},
post(url, data) {
return instance.post(url, data)
.then(res => res)
.catch(reason => Promise.reject(reason));
},
awaitAll() {
return axios.all(Array.from(arguments))
.then(axios.spread((...responses) => responses))
.catch(reasons => Promise.reject(reasons));
}
};
export default ApiService;
现在在组件中使用它:
ApiService.get(YOUR_GET_URL)
.then(res => {
Console.log(res);
))
.catch(reason => {
console.log(reason);
})
我之前遇到过同样的问题,我发现包含我的 axios 配置的文件在存储令牌时正在加载,所以它在存储之前访问它。
解决方法是,在axios配置中:
const axiosInstance = axios.create({
baseURL: `${API_BASE_URL}`,
headers: {
Accepted: 'appication/json',
'Content-Type': 'application/json',
},
});
axiosInstance.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token');
if (token) {
config.headers.authorization = token;
}
return config;
},
(error) => Promise.reject(error),
);
export default axiosInstance;
之后在需要请求的地方使用这个实例
我正在使用 JWT 令牌身份验证系统,当我登录时,我得到了这样的令牌:
axios.post('/login', data)
.then(response => {
localStorage.setItem('token', response.data.token);
});
这很好用,令牌保存在 localStorage 中。但是,令牌不包含在以后的请求中。 授权 header 是 Bearer null
。
这就是我设置全局 axios 的方式 object。
window.axios = axios.create({
baseURL: '/api/',
timeout: 10000,
headers: {
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-TOKEN': document.head.querySelector('meta[name="csrf-token"]').content,
'Authorization': 'Bearer ' + localStorage.getItem('token')
}
});
如果我刷新站点,令牌 已设置,并且可以正确使用。
编辑:
我通过从 create()
方法中删除 Authorization
header 并使用 window.axios.defaults.headers.common['Authorization']
来让它工作。但是现在Laravel Echo出现了同样的问题。我这样创建实例:
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'xxx',
cluster: 'eu',
encrypted: true,
namespace: 'xxx',
auth: {
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token')
}
}
});
我这样更新 header:
window.setAuthToken = (token) => {
window.axios.defaults.headers.Authorization = 'Bearer ' + token;
window.Echo.options.auth.headers.Authorization = 'Bearer ' + token;
localStorage.setItem('token', token);
}
axios header更新成功,但Echo未更新
问题是您在页面加载时使用了 localStorage.getItem('token')
。当你在 localStorage
中设置它时,你必须在 axios header.
window.axios = axios.create({
baseURL: '/api/',
timeout: 10000,
headers: {
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-TOKEN': document.head.querySelector('meta[name="csrf-token"]').content,
'Authorization': 'Bearer ' + localStorage.getItem('token')
}
});
axios.post('/login', data)
.then(response => {
localStorage.setItem('token', response.data.token);
window.axios.defaults.headers.common['Authorization'] = 'Bearer ' + localStorage.getItem('token');
});
为此使用 axios interceptors。每次请求调用都会运行。
最好将 axios 方法保存在单独的文件中并调用它,而不是直接在所有组件中使用它。这样,如果我们愿意,我们可以用最小的努力用另一个库替换 axios 。这是我在我的项目中所做的。
import axios from "axios";
import AuthService from "./auth";
import config from '../config'
const instance = axios.create({
baseURL: config.apiServer.url,
timeout: config.apiServer.timeout
});
instance.interceptors.request.use(
config => {
const token = AuthService.getToken();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
error => Promise.reject(error)
);
const ApiService = {
get(url) {
return instance.get(url)
.then(res => res)
.catch(reason => Promise.reject(reason));
},
post(url, data) {
return instance.post(url, data)
.then(res => res)
.catch(reason => Promise.reject(reason));
},
awaitAll() {
return axios.all(Array.from(arguments))
.then(axios.spread((...responses) => responses))
.catch(reasons => Promise.reject(reasons));
}
};
export default ApiService;
现在在组件中使用它:
ApiService.get(YOUR_GET_URL)
.then(res => {
Console.log(res);
))
.catch(reason => {
console.log(reason);
})
我之前遇到过同样的问题,我发现包含我的 axios 配置的文件在存储令牌时正在加载,所以它在存储之前访问它。
解决方法是,在axios配置中:
const axiosInstance = axios.create({
baseURL: `${API_BASE_URL}`,
headers: {
Accepted: 'appication/json',
'Content-Type': 'application/json',
},
});
axiosInstance.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token');
if (token) {
config.headers.authorization = token;
}
return config;
},
(error) => Promise.reject(error),
);
export default axiosInstance;
之后在需要请求的地方使用这个实例