单点登陆(SingleSignOn,SSO
),就是经过用户的一次性鉴别登陆。当用户在身份认证服务器上登陆一次之后,便可得到访问单点登陆系统中其余关联系统和应用软件的权限,同时这种实现是不须要管理员对用户的登陆状态或其余信息进行修改的,这意味着在多个应用系统中,用户只需一次登陆就能够访问全部相互信任的应用系统。前端
这里用一张图说明sso流程git
假设zss
系统前端域名为zsstest.zuel.com:8081
,后端域名为zsstest.zuel.com:8887
;sso
系统前端域名为sso.zuel.com:8082
,后端域名为sso.zuel.com:8888
。咱们跟着原理流程图来说解如何实现单点登陆。github
假设zss
系统首页zsstest.zuel.com:8081/index
有一个/api/getUserinfo
请求获取用户信息,当第一次用浏览器打开首页时就发送了该请求,zss-os
后端接收到该请求,发现请求没有携带cookie
身份(也就是token
),返回401
给zss-fe
前端,前端响应拦截器拦截到返回数据,发现返回数据为401
,因而重定向到sso
的登陆页(sso.zuel.com:8082/login
),并把zss
系统首页做为参数拼接到重定向地址的后面(window.location.href=http://sso.zuel.com:8082/login?service=http://zsstest.zuel.com:8081/index
)。当登陆成功时,sso-os
后端根据帐户和时间生成token
(使用jwt
包),经过设置响应头Set-Cookie
属性种下cookie
,并把token
存到redis
集群中,最后重定向到service
参数url
。redis
重定向到service
参数url
又会再次发送/api/getUserinfo
请求,后端zss-os
就会去校验cookie
身份(到redis
集群中去找是否有该身份的token
存在),若校验合法,则返回请求结果,不然返回401
又再次重定向到sso
登陆页。chrome
这里使用redis
集群的目的是zss
系统和sso
系统均可以访问到redis
存储的数据。后端
上面还有许多坑,在设置cookie
时须要注意:api
withCredentials=true
时, 后端配置Access-Control-Allow-Origin
不能为*
, 必须是相应地址withCredentials=true
时, 后端需配置Access-Control-Allow-Credentials
Access-Control-Allow-Headers
为对应的请求头集合set-cookie
若想在浏览器cookie
中显示而且在前端请求头自动携带,那么设置cookie
时domian
就必须与前端当前页域名、请求域名同样。好比,上述domain
设置为.zuel.com
,那么zsstest.zuel.com:8081/index
页面的cookie
将会显示,zsstest.zuel.com:8887/api/getUserInfo
请求头也会自动携带domain
域名的cookie
name、path、domain
相同的cookie
才是同一个cookie
参考:
https://juejin.im/post/5c2490...
https://juejin.im/post/5c0f2a...
https://juejin.im/post/59d1f5...浏览器
单点登陆的实现:
上面生成token
使用了时间,也就是每次登陆成功生成的token
都会不一样,当用户A
使用chrome
登入系统生成的token
为t1
,redis
存储t1
,浏览器cookie
存储t1
,而后用户A
换个Firefox
登陆,生成token
为t2
,redis
存储t2
,浏览器cookie
存储t2
。当用户A
在chrome
刷新页面,请求携带的cookie
仍是t1
,但redis
存储的cookie
已经变成t2
,因此身份验证不会经过,页面会重定向到sso
登陆页服务器
统一登录实现效果:cookie