1.单点登录介绍
在早期开发中,一家公司可能只有一个Server,什么业务都写在一起,也就是早期的Servlet。
随着业务的发展,逐渐的新增了很多的业务Server,这时候每个Server都要进行注册登录的话,那对用户来说简直是奔溃级的体验。
一次注册、一次登录并不困难,但如果每次都登录,应该没什么用户会选择这个系列的产品了吧!
2.何为单点登录?
在业务满天飞的情况下,单点登录是比较流行的企业业务整合的解决方案之一。它的意义在于多个应用系统中,用户只需要登录一次即可访问所有相互信任的系统。
3.实现猜想
一次注册,一次登录,即可畅享所以系列的产品。那么难点在哪里?用户信息的共存共用才是单点登录的难点。首先从服务端和客户端来进行分析
客户端SessionId和服务端Session
凭借着客户端带过来的SessionId,在服务端Session中保存对应SessionId的用户信息,问题也很明显,Session是每个服务端私有的,并不是多个服务之间共用的
那么单点登录实现的方式大概分为两种
- 客户端Cookie,也称为共享Cookie,将用户信息标识通过cookie存放,服务端直接从cookie中获取,这种不是很安全,很难管控
- token模式,所有应用系统共享一个身份认证系统。在首次认证成功后,为该用户生成唯一认证标识(token),客户端不管访问哪个服务均需要带上该认证标识,服务端获取到该标识可以通过(认证服务接口或者共用缓存、DB)获取到对应的用户信息即可。
4.Java代码实现
仅仅只是样例,并不能直接运行,这里使用的是Jwt作为token串,像早期的使用uuid也可以的
static RedisManager redisManager;
public static void main(String[] args) {
//1. 登录
//检验账号密码 状态什么的 。。。
//2. 生成唯一token 返回给前端
//授权
List<GrantedAuthority> authorities = new ArrayList<>();
// 昵称#id
authorities.add(new SimpleGrantedAuthority("用户0002#2"));
authorities.add(new SimpleGrantedAuthority(new Date().getTime() + ""));
String token = JwtUtils.createToken("用户0002",authorities);
log.info("返回前端token:{}",token);
//3.存入缓存 这里使用缓存当做用户信息共享
//存入 用户id -> token 校验是否已失效 也可以设置定期过期
redisManager.set("MEMBER:TOKEN:2",token);
//用户信息存储缓存 map 这里仅举例
redisManager.hPut("MEMBER:INFO:2","nickname","用户002");
//4.其他服务从头部获取token 再从缓存获取用户信息
// String token = getHeaderToken(request);
Claims claims = JwtUtils.parseToken(token);
List<Map<String,Object>> grantedAuthoritys = (List) claims.get(SecurityConstant.CLAIMS);
String uid = null,nickname = null;
for (Map<String, Object> map : grantedAuthoritys) {
if(map.containsValue("#")){
String[] split = map.get("authority").toString().split("#");
uid = split[0];
nickname = split[1];
break;
}
}
log.info("当前用户:{},{}",uid,nickname);
//获取用户信息
Map<Object, Object> userInfo = redisManager.hGetAll("MEMBER:INFO:2");
//5.检验token过期 当前token可能是第二次登录生成的了 那么第一次登录的token应该要失效
token += "1";
String cacheToken = redisManager.get("MEMBER:TOKEN:2");
if(cacheToken != null && !token.equals(cacheToken)) {
log.info("当前token已失效:{}", token);
//可直接报401
}
}
}
目标就是实现一次登录,多服务都可以获取到用户信息,第二次登录后,前面登录的token均失效,每个token只在当前登录次数有效
5.优缺点
- 优点
- 极大的提高了用户体验
- 提高了开发的效率,除认证服务外减少了重复的认证代码
- 简化了token的管理,让token只保存当次登录才有效的原则
- 缺点
- 系统只认token不认操作用户,如果token泄漏的话,可能会导致一些重要信息被修改泄漏
6.总结
单点登录实现的难点,其实就是任意服务怎么实现根据token串获取用户信息共享,这里记录一下之前用到过的实现方式
- redis缓存,毫无疑问肯定是最常见的
- mongo、mysql等db存储,公共库
- 公共认证服务,内网远程调用
如果还有其他的方式实现的,欢迎评论区留言哦
以上就是本章的全部内容了。
上一篇:SpringSecurity第一话 – 一文来吃透SpringSecurity+Jwt权限控制
下一篇:随手记录第二话 – 高并发情况下秒杀、抢红包都有哪些实现方式?
旧书不厌百回读,熟读精思子自知