单点登录的解决方案

背景

项目组的多个子项目想要实现统一登录,也就是多个项目共用一个登录页面,在A项目登录成功时,访问B项目页面时是不用登录的。

先说一波cookie的概念

在浏览器中,打开控制台,选择Application,点击cookie下面的子选项,就可以看到cookie了。
《单点登录的解决方案》
cookie是在服务器端生成的,返回给客户端,由客户端来保存。上图列表中每一条都是一个cookie。

Name :名称,一个唯一确定cookie的名称。
Value : 值,对应的name的值。
Domain :域, cookie对哪个域是有效的,所有向该域发送的请求都会包含这个cookie信息,cookie是绑定在特定的域名下面的。
Path :路径,指定域下面的这个路径的请求, 发送请求时,才会带上这个cookie。
Expires: cookie的过期时间。
HTTP: HttpOnly,客户端脚本是否可访问,上图中打勾的都是不可访问的。

例如 x-auth-token (假定x-auth-token的域为fairy.dev.com) 的 path如果被设置成/books,那么fairy.dev.com/books这个路径下面的请求才会带x-auth-token。
token是写在cookie集合里面的一个cookie。例如图中的 x-auth-token就是token。

统一登录

打开A项目的登录页面fairy.dev.com/login 进入登录页面。
登录页面里面会嵌入一个iframe,把用户名、密码会提交到 统一登录的服务器 id.common.com。登录成功后服务器端会生成一个token返回给客户端。这时token的域是id.common.com ,也就是说,访问fairy.dev.com下面的页面并不会带上这个token,只有访问id.common.com下面的东西,客户端发起请求的时候才会带上这个token。
但是现在我们要进入的主页是fairy.dev.com/index 。所以我们要copy一份这个token,到fairy.dev.com 这个域下面。这个token不是在cookie里面吗?从 document.cookie 直接去拿不就好了嘛?2333,并不行的,服务器端返回的token设置到cookie里面设置成HttpOnly。客户端脚本里面是拿不到的。所以我们要让服务器端返回这个token。
讲道理,输入用户名、密码验证成功就应该跳转到fairy.dev.com/index ,但是,目前我们的cookie里面还没有fairy.dev.com 这个域下面的token。在请求fairy.dev.com/index这个页面的时候, 发一个get请求,采用jsonp的方式,去请求一个id.common.com下面的一个js文件,例如 id.common.com/authApi.js 。
客户端发送这个get请求的时候会带上id.common.com 的token,我们通过这个请求去服务器端请求这个token,当服务器端返回这个token的时候,就会把这个token写到fairy.dev.com这个域下面。
Ok,有了这个域下面的token,那么后面的fairy.dev.com 下面的请求都会带上这个token。登录成功!

那么B项目此时要打开页面是不用登录的,如果项目结构是fairy.dev.com/a 、fairy.dev.com/b这个样子的话,那么这两个都是同一个域,登录成功fairy.dev.com/a,再去访问fairy.dev.com/b自然是可以访问的。
如果是a.dev.com, b.dev.com 这两个项目要共享cookie。当你登录了a.dev.com的时候,我们的cookie里面有了id.common.com 的token。请求b.dev.com下面的页面的时候,同样是用jsonp的方式发一个get请求把服务器端返回的token写到b.dev.com 域下面。b.dev.com下面的页面也就都可以访问了。
至此,我们也就实现了统一登录。下面简单说一下客户端和服务器端设置cookie,大神请略过~

客户端设置cookie vs 服务器端设置cookie

客户端设置cookie,document.cookie 可以访问到,不安全
《单点登录的解决方案》


document.cookie = encodeURIComponent(‘wang’) + “=“ + encodeURIComponent(‘2333’);//就可以在cookie集合中加入 wang=23333
这个字符串会被添加到现有的cookie集合中,设置document.cookie并不会覆盖cookie,除非设置的cookie名称已经存在。
这样添加进cookie集合中的cookie是document.cookie可以访问到的,客户端脚本可以访问的。
《单点登录的解决方案》

如图,可以看到我们添加的wang httpOnly并没有勾选。

服务器端 setCookie,document.cookie 不可访问,相对来说安全一些
通过在响应头里面加一个Set-cookie字段,把cookie写入到cookie集合里面。

如有错误,恳请指正。

猜你喜欢

转载自blog.csdn.net/Smallsun_229/article/details/80721905