上次在项目中作一个手机验证码功能时遇到后端set-cookie
没法成功的问题,相信不少人都会遇到,今天分享出来,算是作个记录,也给有须要的小伙伴一个参考,下面先说一下场景前端
用户输入手机号并点击发送验证码按钮express
此时是向后端服务器发起高请求,传递手机号码
后端接收到手机号码后经过短信服务商的接口发送短信到手机号后端
因为安全性问题,通常服务商的接口都是由后端发起请求,那验证码是怎么来的呢?固然是咱们本身后端生成的(通常是生产一个4位或6位随机数字号码),短信接口只负责发送
问题来了,咱们都知道http请求是无状态的,即每一个请求都是独立的,两个请求间没有任何联系,但上面的步骤中,用户发起了两次请求(第1步和第3步),后端怎么知道是同一我的呢?万一当时有10我的同时获取验证码,且都执行完全部步骤,怎么实现各自第1和第3步的对应关系进而进行第4步校验?因而咱们引入session
跨域
session
是保存的服务器的一个数据存储机制,通常用于存储用户状态数据,你能够理解为客户端的cookie
,由于它们很像,一样是有key/value
和有效时间,只是一个在服务端,一个在客户端。这跟本文有什么关系呢?确定有关系,关系大了去了,否则我写干吗(自嗨中~~~)浏览器
咳~咳。。回归正题,刚刚说了http是无状态的,而咱们如今又要把第1步和第3步关联起来,怎么关联呢?session+cookie出马,具体原理以下安全
第一次接到请求,后关会生成一个sessionid
来标识当前会话(我使用express-session
来实现),并经过set-cookie
响应头在客户端生一个cookie,大概长这样,服务器
connect.sid=s%3Au9xG34DBU1vOVbIpCax0neMxL_Uc1fIC.4ndNJL5G%2B41DtUSLbQ%2BW75Z9wduOAON4lfu2JGTDe5
sessionid
给服务器,服务器经过这个sessionid
来标识是否为同一个用户,问题就迎刃而解了...前端:cookie
后端:session
session
,并给前端响应connect.sid
(express-session会Set-Cookie
响应头)前端:并发
Set-Cookie
响应头后,自动把sessionid
写入浏览器cookie
sessionid
随cookie
自动发送到后端)后端:
session
的随机验证码进行比较,一致则响应成功,不然响应失败经过以上步骤,正常状况下你已经能实现手机验证码功能了,可我恰恰遇到了非正常状况,这也是我今天这篇文章的意义,因为开发阶段为先后端分享,请求是产生了跨域,明明已经正确响应了Set-Cookie
,容许了CORS
跨域,但浏览器的cookie中就是看不到connect.sid
的身影,关键浏览器还不报错。
因而各类千里寻她千百度,最后发现Set-Cookie
在跨域时默认是被浏览器忽略的,解决的方案是两步:
"Access-Control-Allow-Credentials":true
响应头withCredentials:true
请求头搞定,收工,但愿对你有帮助