分布式架构的单点登陆

1.需要实现的功能

①用户在任意模块进行登陆操作后,在系统中其它模块能查询到当前登陆用户的信息

②用户在登陆过一次系统后,应该记忆用户的用户名,下次不必登陆就可以在页面显示用户名,但是实际状态是未登录,且有过期时间

③用户在任意页面的登录按钮,登录后能回到原来的页面.


2.实现的思路

登陆服务单独创建一个用户登陆认证中心模块(分布式,SSO(single sign on)模式

对于第一条:①用户在任意模块进行登陆操作后,在系统中其它模块能查询到当前登陆用户的信息

这个是单点登录的最基本的功能,可以将用户登陆后的信息放在redis缓存中,每次用户登陆就设到缓存中,采用redis的str数据类型.key可以为user:{userId}:info,value可以设置为用户信息的json字符串.

服务中登陆的方法:

//key的前缀
public final String userKey_prefix = "user:";
//key的后缀
public final String userinfoKey_suffix=":info";
//过期时间 一个小时
public final int userKey_timeOut=60*60;

public UserInfo login(UserInfo userInfo) {
        //密码的加密 DigestUtils是加密的工具类
        userInfo.setPasswd(DigestUtils.md5DigestAsHex(userInfo.getPasswd().getBytes()));
        //从数据库中查找用户是否存在
        UserInfo loginUserInfo = userInfoMapper.selectOne(userInfo);
        if(loginUserInfo!=null){
            //redisUtil也是操作redis的工具类
            Jedis jedis = redisUtil.getJedis();
            String key = userKey_prefix+loginUserInfo.getId()+userinfoKey_suffix;
            //保存到redis中
            jedis.setex(key, userKey_timeOut, JSON.toJSONString(LoginUserInfo));
            jedis.close();
        }
        return loginUserInfo;
    }

当其他模块需要用户的登录信息时,就可以根据用户的userId直接去redis中查找.

//根据userId进行登陆认证
    public UserInfo verify(String userId){
        //去缓存中查询是否有对应userId的用户信息
        Jedis jedis = redisUtil.getJedis();
        //拼接key值前缀+userId+后缀
        String key = userKey_prefix+userId+userinfoKey_suffix;
        String userInfoJson = jedis.get(key);
        if(userInfoJson!=null&&userInfoJson.trim().length()>0){
            //给这个key重新设置失效时间
            jedis.expire(key, userKey_timeOut);
            UserInfo userInfo = JSON.parseObject(userInfoJson, UserInfo.class);
            return userInfo;
        }
        return null;
    }

对于第二三条:

②用户在登陆过一次系统后,应该记忆用户的用户名,下次不必登陆就可以在页面显示用户名,但是实际状态是未登录,且有过期时间.

③用户在任意页面的登录按钮,登录后能回到原来的页面.

这两个需求需要利用浏览器的cookie功能或者localStorage本地存储功能.这里只说利用cookie来实现.并利用一个简单的token机制

具体做法为:

  1. 用userId+当前用户登录ip地址+密钥生成token
  2. 重定向用户到之前的来源地址,同时把token作为参数附上。
  3. 将token设置到用户的浏览器cookie中,并设置一个过期时间,通过解密token就可以实现第二个需求

首先页面的所有登陆入口应该用js代码来控制,每次点击登陆按钮登陆时,应该带上一个originUrl的参数,用于保存登陆后需要跳转的页面控制器,一般设置为当前页面

function login(){
      //使用encodeURIComponent()函数对url进行编码
      var s = encodeURIComponent("http://xxx.xxx.com/cartList");
       window.location
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值