一、常用鉴权方式
HTTP Basic Authentication (HTTP基本认证)
session-cookie
1,服务器在接受客户端首次访问时在服务器端创建session,然后保存session(我们可以将session保存在内存中,也可以保存在redis中,推荐使用后者),然后给这个session生成一个唯一的标识字符串,然后在响应头中种下这个唯一标识字符串。
2.签名。这一步只是对sid进行加密处理,服务端会根据这个secret密钥进行解密。(非必需步骤)
3.浏览器中收到请求响应的时候会解析响应头,然后将sid保存在本地cookie中,浏览器在下次http请求的请求头中会带上该域名下的cookie信息,
4.服务器在接受客户端请求时会去解析请求头cookie中的sid,然后根据这个sid去找服务器端保存的该客户端的session,然后判断该请求是否合法。
Token 验证(包括JWT,SSO)
最简单的token组成(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,由token的前几位+盐以哈希算法压缩成一定长的十六进制字符串.
- 2, 服务端收到请求,去验证用户名与密码
- 3, 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
- 4, 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
- 5, 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
## 优点
Token 可以避免 CSRF 攻击(也是因为不需要cookie了)
Token 可以是无状态的,可以在多个服务间共享(服务器也只是做了token的解密和用户数据的查询, 它不需要在服务端去保留用户的认证信息或者会话信息)
Token 支持手机端访问(Cookie不支持手机端访问)
## 缺点:
性能问题: 相比于session-cookie来说,token需要服务端花费更多的时间和性能来对token进行解密验证.其实Token相比于session-cookie来说就是一个"时间换空间"的方案.
token与session的区别:
使用Token,服务端不需要保存状态,服务端是根据session_id,来查询在服务器端保持的session,这里面才保存着用户的登陆状态。但是token本身就是一种登陆成功凭证,他是在登陆成功后根据某种规则生成的一种信息凭证,他里面本身就保存着用户的登陆状态。服务器端只需要根据定义的规则校验这个token是否合法就行。
Token不需要借助cookie的. 我们知道http代理客户端不只有浏览器,还有原生APP等等,这个时候cookie是不起作用的,使用token时,客户端在收到响应的时候,可以把他存在本地的cookie,storage,或者内存中,然后再下一次请求的请求头重带上这个token就行了。
时效性。session-cookie的sessionid实在登陆的时候生成的而且在登出事时一直不变的,在一定程度上安全就会低,而token是可以在一段时间内动态改变的。
可扩展性。token验证本身是比较灵活的,一是token的解决方案有许多,常用的是JWT,二来我们可以基于token验证机制,专门做一个鉴权服务,用它向多个服务的请求进行统一鉴权。
OAuth(开放授权)
- 用户访问系统1的受保护资源,系统1发现用户未登录,跳转至sso认证中心,并将自己的地址作为参数
- sso认证中心发现用户未登录,将用户引导至登录页面
- 用户输入用户名密码提交登录申请
- sso认证中心校验用户信息,创建用户与sso认证中心之间的会话,称为全局会话,同时创建授权令牌
- sso认证中心带着令牌跳转会最初的请求地址(系统1)
- 系统1拿到令牌,去sso认证中心校验令牌是否有效
- sso认证中心校验令牌,返回有效,注册系统1
- 系统1使用该令牌创建与用户的会话,称为局部会话,返回受保护资源
- 用户访问系统2的受保护资源
- 系统2发现用户未登录,跳转至sso认证中心,并将自己的地址作为参数
- sso认证中心发现用户已登录,跳转回系统2的地址,并附上令牌
- 系统2拿到令牌,去sso认证中心校验令牌是否有效
- sso认证中心校验令牌,返回有效,注册系统2
- 系统2使用该令牌创建与用户的局部会话,返回受保护资源
注销:
-
局部会话存在,全局会话一定存在
-
全局会话存在,局部会话不一定存在
-
全局会话销毁,局部会话必须销毁
-
用户向系统1发起注销请求
-
系统1根据用户与系统1建立的会话id拿到令牌,向sso认证中心发起注销请求
-
sso认证中心校验令牌有效,销毁全局会话,同时取出所有用此令牌注册的系统地址
-
sso认证中心向所有注册系统发起注销请求
-
各注册系统接收sso认证中心的注销请求,销毁局部会话
-
sso认证中心引导用户至登录页面
OAuth 2.0
它允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的所有内容,为了保护用户数据的安全和隐私,第三方网站访问用户数据前都需要显式的向用户征求授权。我们常见的提供OAuth认证服务的厂商有QQ,微信,微博等。
二、手机扫二维码登陆的原理
为什么用临时token?
临时token与token一样,它也是一种身份凭证,不同的地方在于它只能用一次,用过就失效。同时防止被坏人拦截token去冒充登录(token和设备是绑定的,故攻击者获取了手机长期token也无法在新设备上使用)
为什么使用多次token?
以此确保扫码,登录两步操作是同一部手机端发出的。
三、谈谈SSO单点登录的设计实现
单点登陆:学校的网站,有很多个系统,迎新系统,教务系统,网课系统,只需要登录一次就能在各个系统中被认定为登录状态。
Cookie共享传播状态
认证中心和其他系统是在一个域名下的,认证中心为父域名(jwxt.com),其他系统是子域名(yx.jwxt.com),或者是同一IP不同端口的情况,我们的服务端通过cookie去判断是否登录。
在认证中心登录成功的时候设置Cookie,domin要设置为父域名(.jwxt.com),设置SameSite,此后子域名的系统也有了Cookie。
Session共享
使用Session共享技术,将Session信息存储在一个外部存储中,比如Redis、MongoDB等,从而实现多个应用程序之间的Session共享。使用一些现成的框架来实现Session共享,比如Spring Session、Apache Shiro。
- 数据库共享:将session存储在数据库中,不同的应用服务器通过访问同一数据库来实现session共享。
- Cookie共享:将session ID存储在cookie中,不同的应用服务器通过访问同一域名下的cookie来实现session共享。
- 缓存共享:将session存储在缓存中,不同的应用服务器通过访问同一缓存来实现session共享。常用的缓存系统有Redis、Memcached等。
Oauth2
基于OAuth2.0的单点登录:OAuth2.0是一种授权框架,可以用于实现单点登录。用户在第一次登录时,服务器会将用户的授权信息存储在OAuth2.0服务器中。当用户访问其他应用程序时,这些应用程序会向OAuth2.0服务器请求授权信息,如果授权信息有效则认为用户已经登录。
![img](https://img-blog.csdnimg.cn/img_convert/cf27e46570ac1b5bb4c7ad41706d9d00.webp?x-oss-process=image/format,png
四 、服务器集群中的session共享方案有哪些?
1、session复制同步方案
解决方式:每个节点都复制其他节点的session
## 优点:
web-server(tomcat)不需要额外开发,只需搭建tomcat集群即可,修改配置文件
## 缺点:
数据传输占用带宽,内存限制
2、cookie客户端存储
解决方式:session存储在客户端的cookie中
## 优点:
服务器不需存储session,用户保存自己的 session信息到cookie中。节省服务端资源
## 缺点:
1.每次http请求,携带用户在cookie中的完整信息,浪费网络带宽
2.session数据放在cookie中,存在泄漏、篡改、窃取等安全隐患
3.session数据放在cookie中,cookie有长度限制4K,不能保存大量信息
3、nginx ip_hash一致性
解决方式:固定的用户固定的请求一台服务器
## 优点:
只需要改nginx配置,不需要修改应用代码
负载均衡,只要hash属性的值分布是均匀的,多台web-server的负载是均衡的
可以支持web-server水平扩展(session同步法是不行的,受内存限制)
## 缺点:
服务器重启可能导致部分session丢失,影响业务,如部分用户需要重新登录
如果服务器水平扩展,rehash后session重新分布,会有用户路由不到正确的session
但是以上缺点问题也不是很大,因为session本来都是有有效期的。所以这两种反向代理的方式可以使用
4、统一存储
解决方式:后端统一存储session
## 优点:
没有安全隐患;
可以水平扩展,数据库/缓存 水平切分即可;
服务器重启或者扩容都不会有session丢失。
## 缺点:
增加了一次网络调用;
如将所有的getSession方法替换为从Redis查数据的方式。
缺点可以用SpringSession完美解决。