前言:
拿到一个需求。中石化公司有很多软件提供商,开发了比较多的系统,现在需要某两家公司(我司和**公司)开发的两个系统只要两个系统中的某一个系统登陆了,另一个系统输入对应的url时,enter就自动登陆,不需要再重新输入用户名和密码登陆。(类似单点登陆);

两个系统之间要统一维护一个用户中心?两个系统要维护同一个user表?可能是吧。
前端做的事情有:
1. 获取登陆页面域名下的cookie(约定一个cookie的key值),有值,直接把这个cookie传给后端,后端去获取对应的权限(验权)和获取用户信息,返回一个url,直接window.open(url),打开,完成自动登陆。
2. 获取登陆页面域名下的cookie(约定一个cookie的key值),无值,就显示登陆页面,用户需要输入用户名密码,提交form表单,调登陆接口。(此时后端的返回response需要设置cookie(约定的那个cookie值),此时,在登陆页面的域就种下了这个cookie,别的系统刷新后,逻辑就和1一样了。)
3. 登陆之后,退出时,需要把cookie(约定的那个cookie)清掉,后端的退出接口可以把cookie属性设置为 expires=当前时间或者max-age=0或者name='';实现清掉功能;
遇到的难点(或者说没有想到的点):
1. 只能获取当前域或者当前域的父域(祖先域)下的cookie,所以假如两个系统的域完全不相同是没办法实现跨域相互信息交流的。也就实现不了两个不相干的系统一个登陆了,另一个可以不用输入用户名密码直接登陆的功能,所以我们在开发的过程还经历了申请和别的系统相同域名的过程(两个系统挂到同一个域下,都是一个父级域的子域);
2. cookie分为内存cookie和硬盘cookie,顾名思义就是存储在内存中的cookie,和存储在硬盘中的cookie,如果是内存cookie,那么一旦关闭当前浏览器窗口cookie就失效了,如果是硬盘cookie,那么它是不会根据浏览器关闭而失效的,它只会根据最初设置它的生命周期的时间而失效,没到时间它就一直有效;那么怎么样在生成cookie时设置是内存cookie还是硬盘cookie呢?如果在生成cookie时有设置cookie的最大生存时间而不是让它使用默认值,那么它就是硬盘cookie,如果没有设置这一步,而是默认的最大生存时间,那么它就是内存cookie。所以我们输入用户名密码登陆必须要设置时间,让他设置为硬盘cookie,不会因为登陆后url跳转关闭登陆也标签页后,假如是内存cookie会自动清掉内存,从而无法在父级域下设置cookie(设置了之后因为登陆页签关闭而从内存中清掉);参考
3. 设置cookie是后端接口返回的response里设置的,不是前端document.cookie设置,只有后端设置才可以往cookie里面存后端使用cookie 鉴权/找用户信息 时需要的信息啊。所以不是前端设置cookie的,前端自测的时候可以自己设置,这样的话登陆的用户在后端找不到就是了,取默认值走else逻辑。
cookie常用属性:

单点登陆重点要关注的domain属性:
- domain表示的是cookie所在的域,默认为请求的地址,如网址www.study.com/study,那么domain默认为www.study.com。
- 而跨域访问,如域A为t1.study.com,域B为t2.study.com,那么在域A生产一个令域A和域B都能访问的cookie就要将该cookie的domain设置为.study.com;
- 如果要在域A生产一个令域A不能访问而域B能访问的cookie就要将该cookie的domain设置为t2.study.com。
- 在任何域名下,cookie的domain参数都只能指定为当前域名或上级域名(包括上级的上级,等等),此外都是无效的。
- 如:在t.a.b.com下,指定domain为t.a.b.com、a.b.com、b.com都是可行的。
- 如果不指定domain,则cookie无法在其他任何域名下被访问,即使是子域名。
- 指定domain与不指定domain的cookie是不相同的,即使下面的情况所产生的cookie也是不同的:
- case1:在a.b.com下,设置无domain参数的cookie。
- case2:在a.b.com下,设置domain=a.b.com的cookie。 case1和case2所生成的cookie是完全不同的。
cookie的缺点:
- cookie可能被禁用。当用户非常注重个人隐私保护时,他很可能禁用浏览器的cookie功能;
- cookie是与浏览器相关的。这意味着即使访问的是同一个页面,不同浏览器之间所保存的cookie也是不能互相访问的;
- cookie可能被删除。因为每个cookie都是硬盘上的一个文件,因此很有可能被用户删除;
- cookie安全性不够高。所有的cookie都是以纯文本的形式记录于文件中,因此如果要保存用户名密码等信息时,最好事先经过加密处理。
cookie相关的方法:
// 获取cookie getCookie (name) { let reg = new RegExp(`(^| )${name}=([^;]*)(;|$)`) let arr = document.cookie.match(reg) if (arr) { return unescape(arr[2]) } else { return null } }
// 设置cookie setCookie (name, value) { let Days = 30 let exp = new Date() exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 30) document.cookie = `${name}=${escape(value)};expires=${exp.toGMTString()}` }
// 删除cookie delCookie (name) { let exp = new Date() exp.setTime(exp.getTime() - 1) let cval = this.getCookie(name) if (cval != null) { document.cookie = `${name}=${cval};expires=${exp.toGMTString()}` } }