随手记录第一话 -- Java中的单点登录都有哪些实现方式?

1.单点登录介绍

在早期开发中,一家公司可能只有一个Server,什么业务都写在一起,也就是早期的Servlet。
随着业务的发展,逐渐的新增了很多的业务Server,这时候每个Server都要进行注册登录的话,那对用户来说简直是奔溃级的体验。
一次注册、一次登录并不困难,但如果每次都登录,应该没什么用户会选择这个系列的产品了吧!

2.何为单点登录?

在业务满天飞的情况下,单点登录是比较流行的企业业务整合的解决方案之一。它的意义在于多个应用系统中,用户只需要登录一次即可访问所有相互信任的系统。

3.实现猜想

一次注册,一次登录,即可畅享所以系列的产品。那么难点在哪里?用户信息的共存共用才是单点登录的难点。首先从服务端和客户端来进行分析
客户端SessionId和服务端Session
凭借着客户端带过来的SessionId,在服务端Session中保存对应SessionId的用户信息,问题也很明显,Session是每个服务端私有的,并不是多个服务之间共用的

那么单点登录实现的方式大概分为两种

  1. 客户端Cookie,也称为共享Cookie,将用户信息标识通过cookie存放,服务端直接从cookie中获取,这种不是很安全,很难管控
  2. 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.优缺点

  1. 优点
  • 极大的提高了用户体验
  • 提高了开发的效率,除认证服务外减少了重复的认证代码
  • 简化了token的管理,让token只保存当次登录才有效的原则
  1. 缺点
  • 系统只认token不认操作用户,如果token泄漏的话,可能会导致一些重要信息被修改泄漏

6.总结

单点登录实现的难点,其实就是任意服务怎么实现根据token串获取用户信息共享,这里记录一下之前用到过的实现方式

  1. redis缓存,毫无疑问肯定是最常见的
  2. mongo、mysql等db存储,公共库
  3. 公共认证服务,内网远程调用

如果还有其他的方式实现的,欢迎评论区留言哦

以上就是本章的全部内容了。

上一篇:SpringSecurity第一话 – 一文来吃透SpringSecurity+Jwt权限控制
下一篇:随手记录第二话 – 高并发情况下秒杀、抢红包都有哪些实现方式?

旧书不厌百回读,熟读精思子自知

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值