JWT使用简介

前言:本文主要简单介绍了什么是JWT和在JavaEE环境下如何使用JWT,简述JWT技术能够为Web开发带来什么样的帮助。

简介

JWT(JSON Web Token),可以生成一个加密的token,作为用户登录的令牌,当用户登录成功之后,发送给客户端。请求需要登录的资源或者接口的时候,将token携带,后端验证token是否合法。提供JSON形式作为Web应用中的令牌,用于在各发之间安全地将信息作为JSON对象传输。在数据传输过程中还可以完成数据加密、签名等处理。

作用

  1. 授权
    最常见方案:JWT。一旦用户登录,每个后续请求将包含JWT,从而允许用户访问该令牌允许的路由、服务和资源。单点登录是当今广泛使用JWT的一项功能,因为开销很小并且可以在不同的域中轻松使用。
  2. 信息交换
    JWT能在各方之间安全地传输信息,因为可以对JWT进行签名,所以可以确保发件人真实性。此外,由于签名是使用标头和有效负载计算的,因此还可以验证内容是否被篡改。

两种认证方式

基于传统的Session认证

在这里插入图片描述

基于JWT认证

在这里插入图片描述

JWT组成

  • Header:标头,头部信息(固定),令牌类型和所使用的签名算法

    变量作用
    密钥用于比对
    算法将Header和Payload加密成Signature
    {
      "alg": "HS256",
      "typ": "JWT"
    }
    
  • Playload:有效载荷,存放信息(可以被解密,不安全),不能存放敏感信息

    变量作用
    签发人Token令牌归属人
    创建时间令牌创建时间
    失效时间令牌失效时间
    唯一标识算法生成的唯一标识(jti -> sessionId)
    {
      "sub": "1234567890",
      "name": "John Doe",
      "iat": 1516239022
    }
    
  • Verify Signature:签名,Header和Playload加上密钥加密而成,用于比对信息,防止篡改Header和Playload

JWT验证,主要验证 Verify Signature 部分是否合法

优势

  1. 简洁
    数据量小,传输速度快
  2. 自包含
    负载中包含了所有用户所需要的信息,避免了多次查询数据库

依赖包

jjwtjava-jwt

<!-- jjwt -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
<!-- java-jwt -->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.18.2</version>
</dependency>

使用JWT

引入依赖

java-jwt是Java推荐使用的JWT实现库

<!-- java-jwt -->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.18.2</version>
</dependency>

生成令牌 token

HashMap<String, Object> map = new HashMap<>();	// Header
// 设置过期时间 600s
Calendar instance = Calendar.getInstance();
instance.add(Calendar.SECOND, 600);
// 创建Token令牌
String token = JWT.create()
    .withHeader(map)                            // Header
    .withClaim("userId", 21)        		   // Payload
    .withClaim("username", "张三")			 // Payload
    .withExpiresAt(instance.getTime())          // 指定令牌过期时间
    .sign(Algorithm.HMAC256("!WENCLJNE"));      // 签名
// 输出令牌
System.out.println("token = " + token);
// 输出结果:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MzIwMzQyNTgsInVzZXJJZCI6MjEsInVzZXJuYW1lIjoi5byg5LiJIn0.iaPw0l_7i0Ff96AzKd-RTm7S1p1WJYePbKF29n6hmJ0

验证令牌 token

JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("!WENCLJNE")).build();	// 创建验证对象
DecodedJWT verify = jwtVerifier.verify(token);	// 验证token
System.out.println(verify.getClaim("userId"));
System.out.println(verify.getClaim("username"));
System.out.println("过期时间:" + verify.getExpiresAt());

常见异常

  • SignatureVerificationException:签名不一致
  • AlgorithmMismatchException:算法不匹配
  • TokenExpiredException:令牌过期
  • InvalidClaimException:失效的payload异常

封装工具类

JwtUtils.java

public class JWTUtils {
    private static String TOKEN = "token!Q@W3e4r";
    /**
     * 生成token
     * @param map  //传入Payload
     * @return 返回token
     */
    public static String getToken(Map<String,String> map){
        JWTCreator.Builder builder = JWT.create();
        map.forEach((k,v)->{
            builder.withClaim(k,v);	// Payload 有效载荷
        });
        // 设置过期时间 7秒
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.SECOND,7);
        builder.withExpiresAt(instance.getTime());
        return builder.sign(Algorithm.HMAC256(TOKEN));	// 签名
    }
    /**
     * 验证token
     * @param token
     * @return
     */
    public static void verify(String token){
        JWT.require(Algorithm.HMAC256(TOKEN)).build().verify(token);  // 如果验证通过,则不会把报错,否则会报错
    }
    /**
     * 获取token中payload
     * @param token
     * @return
     */
    public static DecodedJWT getToken(String token){
        return JWT.require(Algorithm.HMAC256(TOKEN)).build().verify(token);
    }
}
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值