单点登录
最近实训要写认证系统. 看到学弟/学妹想要复用之前集市的认证系统有点麻烦, 感觉还是把认证系统单独抽出来更好一些. 浅浅写一下单点登录模式.
简介
在最开始, 集市还只有一个项目, 认证系统有一份就够了. 但是项目增多, 如果每个项目都实现一套认证系统就会很麻烦, 用户还不同步. 这时候就需要单点登录了.
单点的意思是大家都在一个地方登录, 然后就可以访问各个服务了.
模式
单点登录有这么几种常见的模式. 这里把认证系统叫做AuthService
吧.
session+cookie
用户在AuthService登录后, AuthService需要生成一个sessionId(sid), 然后存起来, 一般会存在redis里作为key, value的话一般是用户信息, username, user_id之类的. 然后再把sid发给用户, 存到cookie里.
这个sid还需要设置域, 比如是example.com, 那么domain就应该是.example.com, 这样子a.example.com也能访问这个cookie了.
用户拿到这个sid后, 就可以访问其它服务了.
其它服务拿到这个sid后, 向AuthService验证sid, AuthService可以把存的用户信息顺便发给服务, 也可以不发, 反正有个验证结果就行.
这种验证方法有一个明显的优点, 那就是控制力强. 如果有一个用户违规了, 需要登出, AuthService只需要把对应的sid删掉就可以了. 这样其它服务验证sid时, 就会验证失败.
但是缺点也挺明显的. AuthService压力会特别大, 毕竟处理所有服务的认证. 如果某个或者某些服务用户量增大了, AuthService也得跟着扩容.
单token
用户在AuthService登录后, 拿到一个token. 之后用户再拿着这个token去访问其它服务.
包括AuthService在内, 所有服务都共享一个密钥来校验token, 因此其它服务不需要访问AuthService, 自己就可以校验token了.
优点是AuthService压力相当小了, 而且服务用户量增大也不没AuthService事.
缺点是控制力变弱了. 如果一个用户违规需要登出, 那么需要通知所有服务才行, 实现起来可能有点复杂. 大概需要共享一份黑名单了.
双token
用户在AuthService登录后, 拿到两个token, 一个是refreshToken, 另一个是accessToken.
refreshToken过期时间比较长, accessToken过期时间比较短.
之后用户拿着accessToken去访问服务, accessToken跟之前的单token一样, 服务自己就可以校验token.
当accessToken过期后, 用户再拿着refreshToken去刷新token.
这算是一个比较折中的办法了. AuthService压力也不会太大, 控制力也不会太弱.