之前项目突然有个接口报401
,经排查后,发现在测试环境是没问题的,只有在本地启的服务才有问题。
复制接口地址在浏览器直接访问也没问题。
经过对比后发现是本地的请求和测试环境的 Cookie
不一致造成的。筛出本地没有携带的 Cookie
项发现是由于有的Cookie设置了Secure
.
标记为
Secure
的 Cookie 只应通过被 HTTPS 协议加密过的请求发送给服务端。它永远不会使用不安全的 HTTP 发送(本地主机除外)。 JavaScriptDocument.cookie
API 无法访问带有HttpOnly
属性的 cookie;此类 Cookie 仅作用于服务器。例如,持久化服务器端会话的 Cookie 不需要对 JavaScript 可用,而应具有HttpOnly
属性。此预防措施有助于缓解跨站点脚本(XSS) (en-US)攻击。
确定是由于本地启的服务是http
方式导致的。如果用https
启动应该不会有问题。
解决办法
由于之前的项目版本低,需要升级webpack-cli,webpack-dev-server
到4.X,升级以后配置
devServer: {
static: {
directory: path.join(__dirname, './dist'),
},
host: 'dev.baidu.com',
hot: true,
// 这个用来让项目接管路由,不加的话刷新页面是404
historyApiFallback: true,
https: true,
port: 8091,
proxy: {
'/api': {
// 这个是错误的
// target: 'http://www.baidu.com',
// 这样才是对的
target: 'https://www.baidu.com',
// pathRewrite: {'^/api' : ''},
changeOrigin: true,
secure: false,
},
},
// 加这个是为了让错误信息显示在控制台不全屏显示
client: {
overlay: false,
},
},
结果由于target
没有改成https
,接口先302一次又到401一次。在第一次带上了secure的Cookie,跳转的时候所有Cookie都丢失了。
关键点
所以遇到这样的问题就是把本地的webpack启动的服务改为支持https,并切记把target改为https的地址。
一直找不到哪里跳转的,尝试将Cookie主动加到请求头里看能不能解决。
试过的方法(注意以下的方法都不生效):
- 在axios的全局加Header的cookie。
axios.defaults.headers.common['Cookie'] = 'session_id=123';
- 在请求拦截层做处理,拿到Cookie后加到请求中。
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
console.log(document.cookie,'22222222')
config.Cookie = document.cookie + ';aaaaaaaaaaaa=2222222222222222222222222222222222;'
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
-
删除原有
Cookie
再重新setCookie
,增加path参数和domain的配置,结果都不生效。 如果是secure为true的不能新增同名的Cookie,也不能删除。其他的Cookie是可以这样操作的。 -
之前做项目的时候遇到过通过
js
无法获取到Cookie
,因为Cookie
设置了httpOnly
属性。
总结
- 遇到
http
状态码是401
时,可以看是否是没携带所有的Cookie
, 尝试升级服务支持https
试试。 - 对
secure
为true
的Cookie,想在JS层面修改是不生效的。 - 对
axios
请求默认增加Cookie
也不生效。