什么是 JWT -- JSON WEB TOKEN,字节Java高工面试

私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。

定义一个payload:


{

  "sub": "1234567890",

  "name": "John Doe",

  "admin": true

} 

然后将其进行base64加密,得到Jwt的第二部分。


eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

3、signature

jwt的第三部分是一个签证信息,这个签证信息由三部分组成:

  • header (base64后的)```

    fetch(‘api/user/1’, {

    headers: {

    'Authorization': 'Bearer ' + token
    

    }

    })

    
    
    
    
  • payload (base64后的)

  • secret

这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。


// javascript

var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);



var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

将这三部分用.连接成一个完整的字符串,构成了最终的jwt:


 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

注意:secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。

八、如何应用


一般是在请求头里加入Authorization,并加上Bearer标注:

服务端会验证token,如果验证通过就会返回相应的资源。整个流程就是这样的:

九、JWT工具类



@Configuration

@ConfigurationProperties(prefix = "jwt.token")

public class JwtTokenUtil {

    public static void setSecret(String secret) {

        JwtTokenUtil.secret = secret;

    }



    public static void setExpiration(int expiration) {

        JwtTokenUtil.expiration = expiration;

    }



    private static String secret="winner";

    private static int expiration=7200;

    private static final String CLAIM_KEY_USERNAME="sub";

    private static final String CLAIM_KEY_ID="id";

    private static final String CLAIM_KEY_CREATED="created";

    private static final String CLAIM_KEY_ROLES="roles";



    //获得的token中得到用户

    public static String getUsernameFromToken(String token){

        String username;

        try {

            username=getClaimsFromToken(token).getSubject();

        }catch (Exception e){

            username=null;

        }

        return username;

    }



    //获得token中的时间

    public static Date getCreatedDateFromToken(String token){

        Date date;

        try {

            final Claims claims=getClaimsFromToken(token);

            date=new Date((Long)claims.get(CLAIM_KEY_CREATED));

        }catch (Exception e)

        {

            date=null;

        }

        return date;

    }



    //从token中获得过期时间

    public static Date getExpirationDateFromToken(String token) {

        Date expiration;

        try {

            final Claims claims = getClaimsFromToken(token);

            expiration = claims.getExpiration();

        } catch (Exception e) {

            expiration = null;

        }

        return expiration;

    }



    //解析token

    private static Claims getClaimsFromToken(String token){

        Claims claims;

        try {

            claims = Jwts.parser().setSigningKey(secret).parseClaimsJwt(token).getBody();

        }catch(ExpiredJwtException e){

            claims=e.getClaims();

        }

        return claims;

    }



    //生成过期时间

    private static Date generateExpirationDate(){

        //过期事件



        return new Date(System.currentTimeMillis()+ expiration);

    }



    //userDetails中的信息加入到token并调用generateToken生产token

    public static String generateToken(Employee userDetails){

        Map<String,Object> claims=new HashMap<>();

        claims.put(CLAIM_KEY_USERNAME,userDetails.getUsername());

        claims.put(CLAIM_KEY_CREATED,new Date());

        claims.put(CLAIM_KEY_ID,userDetails.getENo());

        claims.put(CLAIM_KEY_ROLES,userDetails.getRoles());

        return generateToken(claims);

    }

//            Jwts.builder()

//            .setClaims(map)

                .claim("authorities","admin")

//            .setExpiration(new Date(System.currentTimeMillis() + 7 * 60 * 1000))

//            .signWith(SignatureAlgorithm.HS512, "tmax")

//            .compact();

    //生产token

    public static String generateToken(Map<String,Object> claims){

        return Jwts.builder()

//                .claim("xx","xxx")

                .setClaims(claims)

                .setExpiration(generateExpirationDate())

                .signWith(SignatureAlgorithm.HS512,secret)

                .compact();

    }



    //判断是否在是否在过期时间之前

    private static Boolean isTokenExpired(String token){

        final Date expiration=getExpirationDateFromToken(token);

        return expiration.before(new Date());

    }



    //判断是否可以刷下

    public static Boolean canTokenBeRefreshed(String token){

        return !isTokenExpired(token);

    }



    //刷新token把CLAIM_KEY_CREATED刷新了

    public static String refreshToken(String token){

        String refreshedToken;

        try{

            final Claims claims=getClaimsFromToken(token);

            claims.put(CLAIM_KEY_CREATED,new Date());

            refreshedToken=generateToken(claims);

        }catch(Exception e){

            refreshedToken=null;

        }

        return refreshedToken;

    }

	

	//判断token是否过期,是否可用

    public static Boolean validateToken(String token, UserDetails userDetails){

        Employee user=(Employee)userDetails;

        final String username=getUsernameFromToken(token);

        final Date created=getCreatedDateFromToken(token);

        return username.equals(user.getUsername())&&isTokenExpired(token);

    }



# **读者福利**

读到这的朋友还可以免费领取一份收集的Java进阶知识笔记和视频资料。

**[资料免费领取方式:关注后,点击这里即可免费领取](https://gitee.com/vip204888/java-p7)**

![秋招我借这份PDF的复习思路,收获美团,小米,京东等Java岗offer](https://img-blog.csdnimg.cn/img_convert/e666ea8d298a3797799d0d0706631c64.png)

**更多笔记分享**

![秋招我借这份PDF的复习思路,收获美团,小米,京东等Java岗offer](https://img-blog.csdnimg.cn/img_convert/50509b2b55697dfab9e3c8453fd302ff.png)

![秋招我借这份PDF的复习思路,收获美团,小米,京东等Java岗offer](https://img-blog.csdnimg.cn/img_convert/3ca1624f959d70fa1a111ad91d49f39d.png)

 created=getCreatedDateFromToken(token);

        return username.equals(user.getUsername())&&isTokenExpired(token);

    }



# **读者福利**

读到这的朋友还可以免费领取一份收集的Java进阶知识笔记和视频资料。

**[资料免费领取方式:关注后,点击这里即可免费领取](https://gitee.com/vip204888/java-p7)**

[外链图片转存中...(img-JHSWRSC8-1628610226031)]

**更多笔记分享**

[外链图片转存中...(img-L478RSmU-1628610226034)]

[外链图片转存中...(img-g1GHnIw7-1628610226035)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值