Jwt令牌技术

1.JWT介绍:

    JWT全称:JSON Web Token (官网: JSON Web Tokens - jwt.io
    JWT的组成: (JWT令牌由三个部分组成,三个部分之间使用英文的点来分割)
  • 第一部分:Header(头), 记录令牌类型、签名算法等。 例如:{"alg":"HS256","type":"JWT"}
  • 第二部分:Payload(有效载荷),携带一些自定义信息、默认信息等。 例如:{"id":"1","username":"Tom"}
  • 第三部分:Signature(签名),防止Token被篡改、确保安全性。将header、payload,并加入指定秘钥,通过指定签名算法计算而来。
    

2.JWT的原理

        首先JWT的头中,含有一种签名算法和其他一些数据,有效载荷中存入自己需要储存进去的数据,然后将  头  和  有效载荷  用base64的编码方式进行编码就得到了一串字符串,然后用这一部分字符串,加上指定的密钥,使用头中包含的签名算法进行加密就得到了数字签名。
        如果签名密钥或者其他任意数据有变动,这个数字签名都会失效。

3.优缺点:

  • 优点:
    • 支持PC端、移动端
    • 解决集群环境下的认证问题
    • 减轻服务器的存储压力(无需在服务器端存储)
  • 缺点:需要自己实现(包括令牌的生成、令牌的传递、令牌的校验)

4.Jwt在Java中的实现

        (1)依赖导入

<!-- JWT依赖-->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
        2.Jwt代码实现
@Test
public void getJwt(){
    //用map集合去存放自定义的有效载荷
    Map<String,Object> claims = new HashMap<>();
    claims.put("id",1);
    claims.put("username","Tom");
    
    String jwt = Jwts.builder()
        .signWith(SignatureAlgorithm.HS256, "lzk") //签名算法   
        .setClaims(claims) //自定义内容(载荷)               
        .setExpiration(new Date(System.currentTimeMillis() + 24*3600*1000)) //设置有效期   
        .compact();
    //输出查看JWT是否生成token成功
    System.out.println(jwt);
}
        3.解析Jwt生成的令牌
/*
注意事项,解析时签名密钥要与创建时一致
解析时的方法也许与创建时的一致
*/
@Test
public void parseJwt(){
    Claims claims = Jwts.parser()
        .setSigningKey("lzk")//指定签名密钥(必须保证和生成令牌时使用相同的签名密钥)  
        .parseClaimsJws("(这里是你要解析的token)")
        .getBody();

    System.out.println(claims);
}

        4.Jwt工具类的编写

public class JwtUtils {
    private static String signKey = "lzk";//签名密钥
    private static Long expire = 43200000L; //有效时间
    /**
     * 生成JWT令牌
     * @param claims JWT第二部分负载 payload 中存储的内容
     * @return
     */
    public static String generateJwt(Map<String, Object> claims){
        String jwt = Jwts.builder()
                .addClaims(claims)//自定义信息(有效载荷)
                .signWith(SignatureAlgorithm.HS256, signKey)//签名算法(头部)
                .setExpiration(new Date(System.currentTimeMillis() + expire))//过期时间
                .compact();
        return jwt;
    }

    /**
     * 解析JWT令牌
     * @param jwt JWT令牌
     * @return JWT第二部分负载 payload 中存储的内容
     */
    public static Claims parseJWT(String jwt){
        Claims claims = Jwts.parser()
                .setSigningKey(signKey)//指定签名密钥
                .parseClaimsJws(jwt)//指定令牌Token
                .getBody();
        return claims;
    }
}

 5.登录功能的使用场景

        一般性在开发中,我们需要将除登录页面的其他页面进行拦截(gateway网关拦截、过滤器、拦截器),需要进行token令牌校验才能让用户访问,否则就会跳转到登录页面

        以下是一个员工登录的Controller层,我们首先调用业务层的查询员工,如果员工有数据,那么就将员工的id,用户名,姓名等你需要的数据放入jwt的有效载荷中,然后调用之前编写的工具类,生成token然后一并返回给前端。

@PostMapping("/login")
    public Result login(@RequestBody Emp emp) {
        //调用业务层:登录功能
        Emp loginEmp = empService.login(emp);


        //判断:登录用户是否存在
        if(loginEmp !=null ){
            //自定义信息
            Map<String , Object> claims = new HashMap<>();
            claims.put("id", loginEmp.getId());
            claims.put("username",loginEmp.getUsername());
            claims.put("name",loginEmp.getName());


            //使用JWT工具类,生成身份令牌
            String token = JwtUtils.generateJwt(claims);
            return Result.success(token);
        }
        return Result.error("用户名或密码错误");
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值