JWT的使用方法

1. JWT的使用

为什么使用JWT,而不使用session?
根据我的了解(大白话),传统session是保存在服务器内存中的,而JWT是保存在浏览器本地的,使用JWT的好处就是不占用服务器的内存,使用session的话每一个用户都占用一点服务器的内存,这样显然不好。
使用JWT的话,由于它是保存在浏览器本地的,不会占用服务器的内存,这是一点好处,在前后端分离的系统中对比session,Jwt会更好一点。

header 和 payload 都是用base64来加密的,他们的本体是json数据,咱们看到的只是用base64加密后的
header里包含的内容是 jwt的类型和加密算法
payload里包含的是 非敏感信息,例如:用户id,账号…等等用户的信息,就是不要放密码,为了安全。

# jwt的结构:
> string ===> header.payload.singnature
### 1.令牌组成
- 1.标头(Header)
- 2.有效载荷(Payload)
- 3.签名 (Signature)
- 因此,JWT通常如下所示 : xxxxxx.yyyyyyy.zzzzzz
  1. 引入依赖
 <!--引入jwt-->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>
  1. 生成Token
   		public final static long EXPIRE_TIME=30*60*1000;//放在类中 ,30分钟的毫秒数
		
		//获取时间,用来做token的过期时间,设置30分钟
		Date date=new Date(System.currentTimeMillis()+EXPIRE_TIME)

        Map<String,Object> map=new HashMap<>();
        String sign = JWT.create().withHeader(map) //header  这个不设置也可以
                .withClaim("userId", 12)//payload 存储非敏感的信息 例如用户账号,不能存密码,防止被人解析
                .withExpiresAt(date)//指定令牌的过期时间
                .sign(Algorithm.HMAC256("!we2123")) ;//签名  保密复杂
        System.out.println(sign); //输出结果
# 生成结果
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MjY1MzQ3OTIsInVzZXJJZCI6MTIsInVzZXJuYW1lIjoiamZwIn0.GhUCPBptbASHng-8DkEFIw9jYB2IWStUj3SEgm53x84
2. 验证token

验证时可以加一个
try {

} catch(){
例如验证出现了异常,就证明验证失败 直接return false;
}

 //创建验证对象
        //验证时一定要跟生成时的 算法 和 签名 一致
        JWTVerifier build = JWT.require(Algorithm.HMAC256("!we2123")).build();
        DecodedJWT verify = build.verify(" 这里放token ");
		/**
		以上两行代码就已经完成验证了,如果没有出异常,就验证成功!
		出现了就是验证失败 ,前提要保证算法一定要一致,不要出现算法不一致异常
		*/
		
		//获取payload存储的信息
        System.out.println(verify.getClaim("userId").asInt()); //存什么类型 就as什么类型,否则为null
		System.out.println(verify.getClaim("username").asString());

        Date expiresAt = verify.getExpiresAt(); // 查看token过期时间
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = simpleDateFormat.format(expiresAt);
        System.out.println(format);
3. jwt验证出现的异常

验证时会先验证签名,再验证令牌有没有过期

# 签名验证异常 (生成时和验证时的签名不一致,会出现此异常)
 - SignatureVerificationException
# 算法不匹配异常  (生成时和验证时的算法不一致,会出现此异常)
 - AlgorithmMismatchException
# 令牌过期异常 (生成时设置的时间超时后,再次验证会出现此异常)
 - TokenExpiredException
# 失效的payload异常  (出现此异常的原因有:可能有人使用base64解析payload,更改了数据payload里解析的数据,再次传过来,验证时会出现此异常)
 - InvalidClaimException

4. 封装工具类
/**
 * @Description
 * @Author 金飞鹏  2021/7/18 9:56
 */
public class JWTUtil {
    //30分钟
    public final static long EXPIRE_TIME=30*60*1000;
    /**
     * 生成token header.payload.sing
     */
    public static String getToken(Map<String, String> map){
        Date date=new Date(System.currentTimeMillis()+EXPIRE_TIME); //默认30分钟过期
        //创建JWT builder
        JWTCreator.Builder builder = JWT.create();
        // payload
        map.forEach((k,v)->{
            builder.withClaim(k,v); //这里可以存放 用户id,用户名
        });
        //指定过期时间,sign ,生成token  这里的签名是指定好的
        //实际项目中可以 接收用户的密码来做签名,这样每一个用户对应一个签名
        java.lang.String token = builder.withExpiresAt(date).sign(Algorithm.HMAC256("1234"));
        return token;
    }

    /**
     * 验证token合法性
     */
    public static boolean verify(String token){
        try {
            //如果抛出异常,证明签名不一致 / token过期
            JWT.require(Algorithm.HMAC256("1234")).build().verify(token);
            return true;
        }catch (Exception e){
            return false;
        }
    }

    /**
     * 获得token中的信息无需secret解密也能获得
     */
    public static String getUserName(String token){
        DecodedJWT decode = JWT.decode(token);
        //假设存储的是一个phone
        String phone = decode.getClaim("phone").asString();
        return phone;
    }
  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值