单点登录
单点登录
单点登录的概念
单点登录(Single Sign On),简称为 SSO,是比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。单点登录在大型网站里使用得非常频繁,例如像阿里巴巴这样的网站,在网站的背后是成百上千的子系统,用户一次操作或交易可能涉及到几十个子系统的协作,如果每个子系统都需要用户认证,不仅用户会疯掉,各子系统也会为这种重复认证授权的逻辑搞疯掉。实现单点登录说到底就是要解决如何产生和存储那个信任,再就是其他系统如何验证这个信任的有效性。
一次登录,全部访问
单系统如何实现登录
- 用户向系统发送登录的信息
- 在系统中进行验证
- 验证成功之后将信息保存到Session中,并创建一个cookie将用户信息保存到cookie中并返回给前端
- 用户后续的请求都携带上cookie,当请求进来之后,服务器从用户请求中查询cookie中携带的session_id(里面保存的就是用户的信息)将用户携带的信息,和保存到Session中的数据进行对比,若是一致则证明已经登录
分布式架构中的单点登录
在分布式系统中,各种功能的实现拆分成为了各个微服务;
问题:
- 在多个系统中的Session是不共享的
- 当客户端请求进来之后也会出现Cookie的跨域问题
跨域问题
跨域问题的产生原因:
协议,域名,端口号------->任意一项不同,就会出现跨域问题
域名的概念---域名是绑定一台主机的IP ,可以通过协议加上域名对一台主机进行访问
域名存在:一级域名(顶级域名);二级域名;三级域名
www.baidu.com--->三级域名
baidu.com--->二级域名
.com--->一级域名
在请求访问时高级的域名对低级的域名就不会有Cookie的跨域问题
[这就意味着,由于域名不同,用户向系统A登录后,系统A返回给浏览器的Cookie,用户再请求系统B的时候不会将系统A的Cookie带过去。]
关于Cookie的跨域问题的解决办法
- 服务端将Cookie写到客户端后,客户端对Cookie进行解析,将Token解析出来,此后请求都把这个Token带上就行了
- 多个域名共享Cookie,在写到客户端的时候设置Cookie的domain。[就是放大域名的意思]
- 将Token保存在SessionStroage中(不依赖Cookie就没有跨域的问题了)
1、 cookie被禁用了能登录吗?-----不能
怎么解决的? -------给用户提示:请您启用浏览器Cookie功能或更换浏览器
2、 一顿绕
用户在A浏览器登录了 B浏览器还用登录吗?-----还是需要登录
PC 客户端还用登录吗? IOS 安卓 APP
Pc 客户端手机安装app 移动端(手机浏览器)
3、 用户登录信息多久过期?
分 客户端 APP: 永久 只有不清除 数据
PC设置时间:只要合理就行 30分钟
4、怎么防止cookie盗用(盗链)?
Cookie****存的时候 不要见名之意
Ip****地址 比对ip
关于Session不共享的问题
单系统登录功能主要是用 Session 保存用户信息来实现的,但我们清楚的是:多系统即可能有多个 Tomcat,而 Session 是依赖当前系统的 Tomcat,所以系统A 的 Session 和系统B 的 Session 是不共享的.
会导致的问题:A系统登陆的用户,无法在B系统上直接使用。
解决Session不共享的方案:
tomcat有一个session同步方案,就是一个传播机制,打个比方有A B C 3台tomcat,这3台tomcat的user信息都在session中并且保持一致,如果其中一台的user信息变化了,那么就会传播至另外两台,则实现同步,这样做没问题,但是仅仅只是在做tomcat集群的时候tomcat很少的时候会用,一旦集群增大,有100台,那么就互相传播吧,传播是需要性能损耗的,那么整个网站的性能就会被拉低,你的网站在你的网络风暴中就会晕死
根据请求的IP进行Hash映射到对应的机器上(这就相当于请求的IP一直会访问同一个服务器)【如果服务器宕机了,会丢失了一大部分Session的数据,不建议】
nginx 非粘性session,说穿了就是一个session绑定传播,起初user的session在tomcatA上,tomcatA宕机了,那么session会把所有的信息传播到tomcatB,以此实现session共享,但是这也有个问题,就是传播的时候需要等待,快的时候1分钟左右,慢的时候要5分钟,用户的耐性有限,所以也不能这么做
把Session数据放在Redis中(使用Redis模拟Session)【建议】
建议将登录功能单独抽取成为一个微服务也就是SSO系统
SSO系统
在分布式架构中因为Session并不被每个系统所共享,所以在分布式架构中单点登录可以借助SSO系统;
- SSO系统生成一个token,并将用户信息存到Redis中,并设置过期时间
- 其他系统请求SSO系统进行登录,得到SSO返回的token,写到Cookie中
- 每次请求时,Cookie都会带上,拦截器得到token,判断是否已经登录
前端页面请求 ----->
nginx--->
网关(过滤器)
- 会判断请求的是不是内部的接口,或者是黑名单内的接口
- 判断是不是需要登录的请求(白名单:访问该名单内的接口,必须登录)
- 若是访问的必须要登录的api接口则需要获取登录用户的若是为NULL则跳转到登录页面
- 若是不需要登录的api接口则可以直接放行.