论坛项目核心功能点

论坛项目核心功能点

分布式情况下的session

采用方案:Jwt+Redis

Jwt工具类,用于生成jwt和解析jwt

package com.yxh.island.util;
/****
包含 header

jwt的头部承载两部分信息:

    声明类型,这里是jwt
    声明加密的算法 通常直接使用 HMAC SHA256
playload

载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分

    标准中注册的声明
    公共的声明
    私有的声明
signature

jwt的第三部分是一个签证信息,这个签证信息由三部分组成:

    header (base64后的)
    payload (base64后的)
    secret

****/
public class JwtHelper {
	//头部base64 对称加密
    private final static String base64Secret = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY=";
    //过期时间
    private final static int expiresSecond = 172800000;

    public static Claims parseJWT(String jsonWebToken) {
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(DatatypeConverter.parseBase64Binary(base64Secret))
                    .parseClaimsJws(jsonWebToken).getBody();
            return claims;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }
   public static String createJWT(Usermin user, Long time) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        //生成签名密钥
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(base64Secret);
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

        //添加构成JWT的参数
        JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT")
                .claim("id", user.getId())
                .claim("userid", user.getUserid())
                .claim("time", time)
                .claim("userpic",user.getUserpic() )
                .claim("useremail", user.getUseremail())
                .signWith(signatureAlgorithm, signingKey);
        //添加Token过期时间
        if (expiresSecond >= 0) {
            long expMillis = nowMillis + expiresSecond;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp).setNotBefore(now);
        }
        //生成JWT
        return builder.compact();
    }
}


这样我们就可以通过传输jwt来安全的获取user的信息了,并且有过期时间,好像看上去是没问题了

但是,真的是这样嘛?

第一次考虑的用户登录流程

用户登录-> 返回jwt -> 使用jwt完成业务

完成业务的过程中:

url 拼接jwt ->后端验证 ->返回结果

那如果这个业务没问题,下次业务的时候时间过期了,是不是又要重新登录,会不会影响用户使用呢?

因此我们考虑每次业务后增加用户过期的时间,提升用户体验

第二次考虑的用户登录流程

url 拼接jwt ->后端验证 成功,加过期时间->返回结果

但我们考虑这样一个场景,如果你在你的电脑上登录了,有另外一个人在另外一个电脑上登录了,是不是第一个登录的账号应该被挤下来?

所以我们要保证一个全局的,只有一个人登录的情况下就只能上第三方的中间件了。

我们在redis中已userid为key存一个 用户的登录时间,每次重新登录的时候刷新redis中的 session,用户传token 的时候我们验证他的jwttoken是不是和redis的时间一致就好了。

所以用户要直接登录的条件就是jwt未过期,redis未过期

我们可以考虑每次都把jwt过期时间快过期的时候加长 ,所以redis我们默认过期时间最好设置的比jwt长一点

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值