前言
最近在做一个后台项目,项目中服务端接口需要在axios请求头中添加cookie信息,在axios封装的时候设置了withCredentials(跨域时是否发送cookie)属性为true,然而在接口请求时并不生效,cookie信息并没有在请求头中,但是sockjs-node服务中是包含有设置的cookie信息。最终解决方案是在设置cookie时,使用domain属性解决了该问题,基于此做以下记录。
基本概念
1. Cookie
Cookie(也叫 Web Cookie 或浏览器 Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie 使基于无状态的HTTP协议记录稳定的状态信息成为了可能。 Cookie主要用于以下三个方面:
- 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
- 个性化设置(如用户自定义设置、主题等)
- 浏览器行为跟踪(如跟踪分析用户行为等)
2. Cookie的一些属性
属性名 | 属性说明 |
---|---|
maxAge | Cookie有效期,单位秒。如果为整数,则该Cookie在maxAge秒后失效。如果为负数,该Cookie为临时Cookie,关闭浏览器即失效,浏览器也不会以任何形式保存该Cookie。如果为0,表示删除该Cookie。默认为-1 |
Expires | Cookie的失效时间,如果Cookie没有设置过期时间,那么 cookie 的生命周期只是在当前的会话中,关闭浏览器意味着这次会话的结束,此时 cookie 随之失效, 现在已经被maxAge属性所取代 |
secure | 它是一个布尔值,指定在网络上如何传输Cookie,默认为false,通过一个普通的http连接传输,标记为true的Cookie只应通过被 HTTPS 协议加密过的请求发送给服务端 |
path | Cookie的使用路径,path标识指定了主机下的哪些路径可以接受 Cookie(该 URL 路径必须存在于请求 URL 中), 例如:如果设置为“/sessionWeb/”,则只有contextPath为“/sessionWeb”的程序可以访问该Cookie,如果设置为“/”,则本域名下contextPath都可以访问该Cookie。注意最后一个字符必须为“/” |
domain | domain标识指定了哪些主机可以访问该Cookie的域名。如果设置为“.google.com”,则所有以“google.com”结尾的域名都可以访问该Cookie。注意第一个字符必须为“.” |
DEMO
假设目前有项目中有两个域名:
- a.b.test.com 下文中以域名1指代此域名
- c.d.test.com 下文中以域名2指代此域名
在域名中,所有域名进行分级,也就是说域名1与域名2都是test.com的子域名
下图所示是在域名1下设置的cookie,然后你会发现在域名2(c.d.test.com)下看不到useName这个属性。这个就是所谓的Cookie跨域的问题。 如果希望设置的userName,域名2也可以获取到,就需要使用到Cookie的domain属性。
我们重点说一下这个Domain属性。一般在实现单点登录的时候会经常用到这个属性,通过在父级域设置Cookie,然后在各个子级域拿到存在父级域中的Cookie值。比如刚才设置的userName属性,在Cookie设置时,添加domain属性。
注:我在下列代码中使用的js-cookie模块,偷了个懒,直接使用项目测试页做Demo示例了,伙伴们可以使用原生js设置😊😊😊
Cookies.set('userName', 'jingjing', { domain: '.test.com' })
这样在域名1和域名2下都可以访问到,用户不用重新登录就可以拿到第一次登录进来时候的用户信息,因为这些用户信息都是存在父级域".test.com"下面,其他页面也可以拿到。
domain: '.test.com'配置中,domain属性值的.test.com第一个字符的.
业务场景
一般这样的操作,适用于单点登录,所谓单点登录是指用户在一个站点如www.studyez.com登录后切换到另一个站点communty.studyez.com时也自动 被community的Server判断为已经登录,反过来,只要用户在community.studyez.com登出后,切换到www.studyez.com时后www的Server也会判断到这一用户已经登出