【Xdclass】JWT鉴权

1. 用户注册功能开发和MD5加密工具类封装

用户注册提交手机号phone、姓名、头像等信息,通过判断手机号来判断是否是新用户

private User parseToUser(Map<String,String> userInfo) {

    if(userInfo.containsKey("phone") && userInfo.containsKey("pwd") && userInfo.containsKey("name")){
        User user = new User();
        user.setName(userInfo.get("name"));
        user.setHeadImg(getRandomImg());
        user.setCreateTime(new Date());
        user.setPhone(userInfo.get("phone"));
        String pwd = userInfo.get("pwd");
        //MD5加密
        user.setPwd(CommonUtils.MD5(pwd));

        return user;
    }else {
        return null;
    }

}

如果想要更安全一点,可以对MD5后的值再进行一次MD5
具体原理参考如下MD5加密概述,原理及实现

2.单机和分布式应用的登录校验解决方案

2.0. Session原理

Session原理
当访问服务器一个网页的时候,会在服务器端的内存里开辟一块内存,这块内存就叫做session,而这个内存是跟浏览器关联在一起的(浏览器在session就在)。Session用来记录一系列状态。
Session与cookie功能效果相同。Session与Cookie的区别在于Session是记录在服务端的,而Cookie是记录在客户端的。

Cookie
Cookie包含用户个人信息,再次通过浏览器发送给服务器时,会放在http响应头(弥补HTTP协议无状态的不足,即一次连接完成后打开新的页面就无法追踪上一个页面信息,有了Cookie服务器会记住我)

2.1. 单机tomcat应用登录检验

  • 用户登录成功,服务端会保存一个session,当然客户端客户端有一个sessionId
  • 客户端会把sessionId保存在cookie中,每次请求都会携带这个sessionId

2.2. 分布式应用中session共享

  • 真实的应用不可能单节点部署,所以就有个多节点登录session共享的问题需要解决
  • tomcat支持session共享,但是有广播风暴;用户量大的时候,占用资源就严重,不推荐
  • 使用redis存储token:
    • 服务端使用UUID生成随机64位或者128位token,放入redis中,然后返回给客户端并存储在cookie中
    • 用户每次访问都携带此token,服务端去redis中校验是否有此用户即可

3.分布式应用下登录检验解决方案 JWT

JWT详解

3.1. 从token开始

token : 客户端使用用户名和密码请求登录,服务端收到请求,验证用户名和密码成功后会签发一个token,再把这个token返回给客户端。客户端收到token后可以把它存储起来,比如放到cookie中客户端每次向服务端请求资源时需要携带服务端签发的token,可以在cookie或者header中携带。

3.2. JWT是啥

JWT:就是上述流程当中token的一种具体实现方式,其全称是JSON Web Token,官网地址:https://jwt.io/ 通俗地说,JWT的本质就是一个字符串(以JSON加密形式保存在客户端),它是将用户信息保存到一个Json字符串中,然后进行编码后得到一个JWT token,并且这个JWT token带有签名信息,接收后可以校验是否被篡改,所以可以用于在各方之间安全地将信息作为Json对象传输。

3.3. 为什么用JWT

为什么用JWT:
1.生产的token可以包含基本信息,比如id、用户昵称、头像等信息,避免再次查库
2.存储在客户端,不占用服务端的内存资源
3.狂操session:JWTtoken单点登录友好,使用Session进行身份认证的话,由于cookie无法跨域,难以实现单点登录。但是 token可以被保存在客户端的任意位置的内存中,不一定是cookie,所以不依赖cookie。适合移动端应用:使用Session进行身份认证的话,需要保存一份信息在服务器端,而且这种方式会依赖到Cookie(需要 Cookie 保存 SessionId),所以不适合移动端。(本质都是session依赖保存在本地的cookie)

3.3. JWT使用步骤

使用步骤:
1.首先,前端通过Web表单将自己的用户名和密码发送到后端的接口,一般是一个POST请求(建议HTTPS)。
2.后端核对用户名和密码成功后,将包含用户信息的数据作为JWT的Payload,将其与JWT Header分别进行Base64编码拼接后签名,形成一个JWT Token,形成的JWT Token就是一个如同lll.zzz.xxx的字符串。
3.后端将JWT Token字符串作为登录成功的结果返回给前端。前端可以将返回的结果保存在浏览器中,退出登录时删除保存的JWT Token即可。
4.前端在每次请求时将JWT Token放入HTTP请求头中的Authorization属性中(解决XSS和XSRF问题)。
5.后端检查前端传过来的JWT Token,验证其有效性,比如检查签名是否正确、是否过期、token的接收方是否是自己等等。
6.验证通过后,后端解析出JWT Token中包含的用户信息,进行其他逻辑操作(一般是根据用户信息得到权限等),返回结果。

  • 引入依赖
  • 将user对象包装成token
  /**
     * 根据用户信息,生成令牌
     * @param user
     * @return
     */
    public static String geneJsonWebToken(User user){

        String token = Jwts.builder().setSubject(SUBJECT)
                .claim("head_img",user.getHeadImg())
                .claim("id",user.getId())
                .claim("name",user.getName())
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRE))
                .signWith(SignatureAlgorithm.HS256,SECRET).compact();

        token = TOKEN_PREFIX + token;


        return token;
    }
 - 检查token
  /**
     * 校验token的方法
     * @param token
     * @return
     */
    public static Claims checkJWT(String token){

        try{

            final  Claims claims = Jwts.parser().setSigningKey(SECRET)
                    .parseClaimsJws(token.replace(TOKEN_PREFIX,"")).getBody();

            return claims;

        }catch (Exception e){
            return null;
        }

    }

3.4. JWT结构

JWT由3部分组成:标头(Header)、有效载荷(Payload)和签名(Signature)。在传输的时候,会将JWT的3部分分别进行Base64编码后用.进行连接形成最终传输的字符串。

  • 头部:主要是描述签名算法
  • 负载:主要描述是加密对象的信息,如用户的id等,也可以加些规范里面的东西,如iss签发者,exp 过期时间,sub 面向的用户
  • 签名:主要是把前面两部分进行加密,防止别人拿到token进行base解密后篡改token
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

|7_7|

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值