eyb:JWT介绍


目录:

(1)常见认证机制 

(2)什么是JWT 

(3)JWT快速Demo

(4)解析token 

(5)token过期时间

(6)自定义负载声明


 

(1)常见认证机制 

浏览器访问服务器的时候,会先去认证,认证的时候回传过来用户名和密码,让服务器进行相应的认证,认证通过会在创建session,同时在浏览器段创建Cookie对象,而且会把session放到Cookie里面,那下次我们客户端在进行相应访问的时候,客户端就会带上Cookie对象,服务器会受到Cookie对象,Cookie里面有session对象,拿session对象和服务器本身的session对象进行匹配实现转态的管理,如果是一至呢就返回相应的信息 ,关闭浏览器的时候呢Cookie会被删除,但是我们可以修改Cookie的失效时间使Cookie在一定时间内有效

 

 

5.1.4:

浏览器请求服务器的授权,带上用户名和密码请求登录,服务端受到请求会去验证请求和 密码,验证通过就会返回一个令牌,这个令牌会发给客户端,直接返回token,客户端受收到token以后,会把它存储起来,也是放在Cookie里面的,客户端每当向服务端请求资源的时候呢,就会带上服务端签发的token,服务端收到请求之后呢,就会验证客户端请求里面呢是否带着token,如果验证成功就会返回相应的数据,相对于第一种的验证更安全,相比第二种,第二种会创建session对象,令牌对应的字符串,字符创会比字符串资源更少,会比Cookie的认证方式节省更多的认证资源

 (2)什么是JWT

 

 

 

 (3)JWT快速Demo

 测试类:JjwtdemoApplicationTests

package com.xxxx.jjwtdemo;

import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.Base64Codec;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Date;

@SpringBootTest
class JjwtdemoApplicationTests {

    @Test
    public void testCreateToken() {
        //创建JwtBuilder对象
        JwtBuilder jwtBuilder= Jwts.builder()
                //声明的标识{"jti":"8888}
                .setId("8888")
                //主体,用户{"sub":"Rose"}
                .setSubject("Rose")
                //创建日期 {"ita":"xxxx"}
                .setIssuedAt(new Date())
                //使用算法
                .signWith(SignatureAlgorithm.HS256,"xxxx");

        //获取Jwt的token
        String token=jwtBuilder.compact();
        System.out.println(token);

        System.out.println("=====================");
        String[] split = token.split("\\.");
        //使用BASE64进行解密
        System.out.println(Base64Codec.BASE64.decodeToString(split[0]));
        System.out.println(Base64Codec.BASE64.decodeToString(split[1]));
        //签名是不能解码的涉及到盐,盐解密出来乱码
        System.out.println(Base64Codec.BASE64.decodeToString(split[2]));
    }

}

运行: 

token:第一部分是头部信息,第二本分是荷载,第三部分是签名

 再一次运行:

发现第一部分都是一样的,第二部分加了签发的时间,每次签发的token是不一样的,在没有盐的情况下是根本没有办法解密的 

(4)解析token 

上面我们已经创建了token,在web应用中呢,这种操作一般是有服务端进行,然后发送给客户端,客户端下次再向服务端发送请求的时候呢,就会携带token,就想电影院看电影,我们创建token的过程中就相当于把票token给客户,那客户进场看电影之前,还需要把票携带过来,我们去验证一下票是不是真的,服务端接收到token,就要解析除token的信息,比如说用户的ID、用户名称等等,根据这些信息我们再去数据库查询,返回响应的结果

下面测试一下来解析token:

package com.xxxx.jjwtdemo;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.Base64Codec;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Date;

@SpringBootTest
class JjwtdemoApplicationTests {

   

    //解析token
    @Test
    public void testParseToken(){
        String  token="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODg4Iiwic3ViIjoiUm9zZSIsImlhdCI6MTY1OTU2ODQzN30.WkjzR3_mu7nVSZOFlJFz7potgHPB7-vwoko1sSTcYZ8";
        //解析token 获取负载中声明的对象
        Claims claims=Jwts.parser()
                .setSigningKey("xxxx")
                .parseClaimsJws(token)
                .getBody();
        System.out.println("id:"+claims.getId());
        System.out.println("subject:"+claims.getSubject());//主体
        System.out.println("issueAt:"+claims.getIssuedAt());//签发日期

    }

}

 (5)token过期时间

我们签发的token是永久生效的,那么token必须有一个失效时间,就想电影票一样,为什么要添加失效时间呢,因为从服务器 发送的token服务器并不会自己做记录,所以说有一个弊端服务器端无法控制某一个token是否立刻失效,只能通过一个过期时间,来判断下一,到达失效时间进行失效的策略

package com.xxxx.jjwtdemo;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.Base64Codec;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.text.SimpleDateFormat;
import java.util.Date;

@SpringBootTest
class JjwtdemoApplicationTests {

    


    //创建token 失效时间
    @Test
    public void testCreateTokenHasExp() {
        //当前系统时间
        long now = System.currentTimeMillis();
        //过期时间
        long exp=now+60*1000;


        //创建JwtBuilder对象
        JwtBuilder jwtBuilder= Jwts.builder()
                //声明的标识{"jti":"8888}
                .setId("8888")
                //主体,用户{"sub":"Rose"}
                .setSubject("Rose")
                //创建日期 {"ita":"xxxx"}
                .setIssuedAt(new Date())
                //使用算法
                .signWith(SignatureAlgorithm.HS256,"xxxx")
                //失效时间
                .setExpiration(new Date(exp));

        //获取Jwt的令牌token
        String token=jwtBuilder.compact();
        System.out.println(token);

        System.out.println("=====================");
        String[] split = token.split("\\.");
        //使用BASE64进行解密把JWT的三部分进行分隔在解密
        System.out.println(Base64Codec.BASE64.decodeToString(split[0]));
        System.out.println(Base64Codec.BASE64.decodeToString(split[1]));
        //签名是不能解码的涉及到盐,盐解密出来乱码
        System.out.println(Base64Codec.BASE64.decodeToString(split[2]));
    }

    //解析token 失效时间
    @Test
    public void testParseTokenHasExp(){
        String  token="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODg4Iiwic3ViIjoiUm9zZSIsImlhdCI6MTY1OTU3MjkyNCwiZXhwIjoxNjU5NTcyOTg0fQ.OP22h4k0fSirMlWUYMOGHkfrcgU3sMXOv13Tb2uj3C0";
        //解析token 获取负载中声明的对象
        Claims claims=Jwts.parser()
                .setSigningKey("xxxx")
                .parseClaimsJws(token)
                .getBody();
        System.out.println("id:"+claims.getId());
        System.out.println("subject:"+claims.getSubject());//主体
        System.out.println("issueAt:"+claims.getIssuedAt());//签发日期

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("签发时间:"+simpleDateFormat.format(claims.getIssuedAt()));
        System.out.println("过期时间:"+simpleDateFormat.format(claims.getExpiration()));
        System.out.println("当前时间:"+simpleDateFormat.format(new Date()));

    }

}

 

 

在1分钟之内运行:

 

 超过失效时间1分钟之内运行解析token:报异常

(6)自定义负载声明

package com.xxxx.jjwtdemo;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.Base64Codec;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.text.SimpleDateFormat;
import java.util.Date;

@SpringBootTest
class JjwtdemoApplicationTests {

    


    //创建token(自定义声明)
    @Test
    public void testCreateTokenClaims() {
        //创建JwtBuilder对象
        JwtBuilder jwtBuilder= Jwts.builder()
                //声明的标识{"jti":"8888}
                .setId("8888")
                //主体,用户{"sub":"Rose"}
                .setSubject("Rose")
                //创建日期 {"ita":"xxxx"}
                .setIssuedAt(new Date())
                //使用算法
                .signWith(SignatureAlgorithm.HS256,"xxxx")
                //自定义声明信息
                .claim("roles","admin")
                .claim("logo","xxx.jpg");

        //获取Jwt的令牌token
        String token=jwtBuilder.compact();
        System.out.println(token);

        System.out.println("=====================");
        String[] split = token.split("\\.");
        //使用BASE64进行解密把JWT的三部分进行分隔在解密
        System.out.println(Base64Codec.BASE64.decodeToString(split[0]));
        System.out.println(Base64Codec.BASE64.decodeToString(split[1]));
        //签名是不能解码的涉及到盐,盐解密出来乱码
        System.out.println(Base64Codec.BASE64.decodeToString(split[2]));
    }

    //解析token(自定义声明)
    @Test
    public void testParseTokenByClaims(){
        String  token="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODg4Iiwic3ViIjoiUm9zZSIsImlhdCI6MTY1OTU3NjY3Nywicm9sZXMiOiJhZG1pbiIsImxvZ28iOiJ4eHguanBnIn0.NtmcmdRQEZBlC8XLXDfsxP_0lJSklFdcYczfICluEO0";
        //解析token 获取负载中声明的对象
        Claims claims=Jwts.parser()
                .setSigningKey("xxxx")
                .parseClaimsJws(token)
                .getBody();
        System.out.println("id:"+claims.getId());
        System.out.println("subject:"+claims.getSubject());//主体
        System.out.println("issueAt:"+claims.getIssuedAt());//签发日期
        //获取自定义声明
        System.out.println("roles:"+claims.get("roles"));
        System.out.println("logo:"+claims.get("logo"));

    }


}

 

 

 (7)扩展JWT内容存储

Jwt可以自定义声明,去扩展存储的内容,需要去继承一个实现类JWT的内容增强器 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

喵俺第一专栏

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

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

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

打赏作者

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

抵扣说明:

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

余额充值