故事背景
前端用的 vue + axios
, 后端用的是 ko2
,用 koa-passport
+ passport-local
帮我处理登录注销,用 koa-generic-session
处理session, koa2-cors
处理跨域
问题描述
今天做登录的时候,发现 接口调用正常,数据正常传递,redis里也有存储相应值
唯独前端页面一直没有设置上cookies,无法保存登录状态。
令人崩溃的解决过程
之前在测试功能的时候,能看见cookie被设置上了,然后我就以为是我这几个库没写对,翻腾来翻腾去,怎么搞都不对,明明和网上的一模一样,但就是拿不到cookie。 捣鼓了几个小时,心态都崩了。
后来又重新起了一个项目A,直接设置cookie,直接浏览器访问接口,cookie看见了。
用前端调用这个接口,cookie还是有(这里忘记清除cookie记录了,本地跑的时候都是localhost)(暴躁老哥)
然后又陷入 怀疑调用库api出错的死循环(崩溃边缘)
然后又试了一下前端调用项目A的接口,cookie没了?(清过cookie), 惊了,怎么一会儿有一会儿没的。
然后多次测试,总算发现,我直接访问接口能设置上cookie,但是前端请求拿不到。
ok,总算找到真正的原因了,而暴躁老哥到这一步的时候已经从下午搞到晚上了。
参考:
非空骑迹 - React,koa2前后端分离项目涉及cookie传递的方法
liyuling52011 - Vue 加入 withCredentials 后无法进行跨域请求
为什么会有这样的问题?
前端 localhost:8080 访问后端 localhost:3000 会出现跨域的问题,我采用的是cors来解决。
但是同时也产生了无法传递cookies的情况,原因如下
默认情况下,跨源请求不提供凭据(cookie、HTTP认证及客户端SSL证明等)
如果发送的是带凭据的请求,但服务器的相应中没有相关的头部,那么浏览器就不会把相应内容交给JavaScript,请求就无法得到结果的数据(浏览器得到了,但是我们请求的方法得不到,因为被浏览器拦截了)
如何解决
为此,在后端 CORS处理 时,设置相应的Header:
// 响应头表示是否可以将对请求的响应暴露给页面
Access-Control-Allow-Credentials: true
// 允许跨域操作的具体域名
Access-Control-Allow-Origin: "http://localhost:8080"
// 允许跨域的HTTP方法
Access-Control-Allow-Methods: ["GET","POST","DELETE"]
// 列出将会在正式请求的 Access-Control-Expose-Headers 字段中出现的首部信息
Access-Control-Allow-Headers: ["Content-Type", "Authorization", "Accept"]
复制代码
然后在前端也作出如下处理:
// 表示跨域请求时是否需要使用凭证
axios.defaults.withCredentials = true
复制代码
问题解决
解决问题花了这么久的时候,归根到底,还是过于暴躁,心态崩盘,外加不扎实的计算机网络基础。 :<