先回顾单系统登录
在我初学JavaWeb的时候,登录和注册是我做得最多的一个功能了(初学Servlet的时候做过、学SpringMVC的时候做过、跟着做项目的时候做过…),反正我也数不清我做了多少次登录和注册的功能了…这里简单讲述一下我们初学时是怎么做登录功能的。
登录:将用户信息保存在Session对象中
如果在Session对象中能查到,说明已经登录
如果在Session对象中查不到,说明没登录(或者已经退出了登录)
注销(退出登录):从Session中删除用户的信息
记住我(关闭掉浏览器后,重新打开浏览器还能保持登录状态):配合Cookie来用
单一服务器模式
基于session的认证
客户端(浏览器端) 访问 服务端 一般是基于session的认证。
客户端首次访问服务端登录成功(认证成功)后,服务端会将该用户信息保存在session容器中,并生成一个session_id放在客户端的cookie中 session_id对应着服务端session容器中该用户信息。
客户端下次访问服务端时,带上session_id的cookie就可以验证服务端是否存在该用户信息,以此来判断是否要进行登录认证。
当用户注销 或 session过期 就session_id无效了。
特点:
- 服务端需要消耗资源存储session信息
- session_id必须存放在客户端cookie中
多服务器模式
在多服务器模式(分布式系统)中,如果还使用session的方式认证,客户端访问服务A认证成功后,再访问另一个模块的服务B还需要进行登录认证,这会让用户体验很差。
(比如: 在豆瓣电影登录成功后,访问豆瓣音乐,豆瓣阅读等还需要登录,用户体验就会很差。)
这个时候的解决办法就是单点登录了。
我们可以将登陆功能单独抽取出来,做成一个子系统,如下图:
做单点登录时,先介绍下什么是单点登录吧
单点登录(single sign on) SSO
在同一个系统的多个服务器中,用户只需要登录一次就可以访问该系统下的所有服务器。
相比于单系统登录,sso需要一个独立的认证中心,只有认证中心能接受用户的用户名密码等安全信息,其他系统不提供登录入口,只接受认证中心的间接授权。间接授权通过令牌实现,sso认证中心验证用户的用户名密码没问题,创建授权令牌,在接下来的跳转过程中,授权令牌作为参数发送给各个子系统,子系统拿到令牌,即得到了授权,可以借此创建局部会话,局部会话登录方式与单系统的登录方式相同。这个过程,也就是单点登录的原理。
单点登录常见的三种方式:
-
session广播机制:通过session复制
-
cookie + redis
(1) redis:在key中生成唯一随机值(ip,用户Id等等),value里面存放数据。
(2)cookie:把redis里面生成key值放到cookie里面
访问项目中其他模块,发送请求带着cookie进行发送,获取cookie值,拿着cookie做事情,然后通过cookie获取的key值到redis里面进行查询,根据key进行查询,能查到数据说明就登录了。
-
JWT:token是按照一定规则生成字符串,包含用户信息,规则是怎么样的,不一定,一般采用通用规则JWT
session广播机制
依旧使用session认证 , 客户端在服务A登录成功后 , 将session复制到其他服务器中。
特点:
- 服务器很多,复制session消耗资源
cookie + redis
客户端访问服务端登录成功后, 将用户信息存放到redis中 key: 用户唯一表示(id等) value:用户信息,再将redis的key放入客户端的cookie中。
客户端访问其他服务时,先拿到cookie中的key去redis中进行查询,查得到说明登录过了。
token
客户端访问服务端登录成功后,根据用户信息生成token令牌,token令牌可以放在客户端cookie中,也可以通过地址栏返回,没有限制。
客户端访问其他服务时只要带着token令牌,服务端解析认证成功后,即可获得用户信息。
特点:
- 服务端不用保存token信息
- 客户端存放token没有限制
总结
单点登录是一种方便用户访问多个系统的技术,用户只需在登录时进行一次注册,就可以在多个系统间自由穿梭,不必重复输入用户名和密码来确定身份。也可以理解为共享一个登录界面。就是说只要在这个登录界面保存用户信息到Cookie,其他子站访问这个跳转到登录,如果Cookie已经存在就可以授权子站登录成功。
为了登录安全在用户表UserInfo中增加 Token字段《用户名+IP地址+随机值》。
1.开始访问A站跳转到总站公共登录页面。
2.登录成功之后,写入Cookie登录信息到总站,设置Cookie.Domain = “总站域名.com”,设置用户表Token票据字段,回到A站并URL传Token值。
3.A站获取Token票据,验证Token IP是否正确,是否在数据中存在。如果匹配就登录成功,设置Session 登录信息。并重置Token 字段。(让Url失效)
4.用户访问B站,跳转之公共登录页面。
5.检查Cookie 是否存在,如果存在直接返回B站并URL传Token值。B站验证Token 验证登录。
6.注销:B站开始注销,注销B站Session,并请求公共登录页面清除Cookie。这样 就注销了。 如果想注销 其他站Session,就再给其他每个站 发送请求,注销。