登录认证(二)—— jwt封装token与解析

JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

这几天在学jwt,首先介绍一下关于jwt的定义及其优缺点, 有人美玉在前我就直接发链接了。

什么是 JWT -- JSON WEB TOKEN——https://www.jianshu.com/p/576dbf44b2ae

在项目中加入jwt

首先在jar包中加入依赖

        <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>

		<dependency>
			<groupId>io.jsonwebtoken</groupId>
			<artifactId>jjwt</artifactId>
			<version>0.6.0</version>
		</dependency>

然后我们写方法

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import javax.xml.bind.DatatypeConverter;
import java.time.Duration;
import java.util.Date;
import java.util.Map;

@Slf4j
public class JwtTokenUtils {

     /**
     * 生成 access_token   正常请求资源时携带的凭证
     * @param subject 签发此jwt的主体,一般是用户id
     * @param claims  储存在jwt里的信息(键值对),一般是放些用户的权限/角色信息
     */

     public static String testGetAccessToken(String subject, Map<String,Object> claims){
        
      //签发人,有效时间,秘钥之后可以在yml文件中配置,之后创建配置初始化类和初始化方法初始
      //化静态数据
return 
generateToken("xiaosun",subject,claims,System.currentTimeMillis(),"xiaosun123^.^");
    }

    /**
     * 签发/生成token
     * issuer 签发人
     * subject 代表这个JWT的主体,即他的所有人,一般是用户ID
     * claims 储存在jwt里的信息(键值对),一般是放些用户的权限/角色信息
     * ttlMillis 有效时间(毫秒)
     * secret 密钥
     */
    public static String generateToken(String issuer, String subject, Map<String, Object> claims, long ttlMillis, String secret) {
        //加密方式 HS256
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        //当前时间戳,并转为日期
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        //String printBase64Binary(byte[])就是将字节数组做base64编码,byte[] parseBase64Binary(String) 就是将Base64编码后的String还原成字节数组。
        byte[] signingKey = DatatypeConverter.parseBase64Binary(secret);
        //这里其实就是new一个JwtBuilder,设置jwt的body
        JwtBuilder builder = Jwts.builder();
        //如果claims不为空,就加到JWT的载荷里面去
        if(null!=claims){
            builder.setClaims(claims);
        }
        if (!StringUtils.isEmpty(subject)) {
            builder.setSubject(subject);
        }
        if (!StringUtils.isEmpty(issuer)) {
            builder.setIssuer(issuer);
        }
        //签发时间
        builder.setIssuedAt(now);
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            //过期时间
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }
        builder.signWith(signatureAlgorithm, signingKey);
        return builder.compact();
    }

    
    /**
     * 解析令牌 获取数据声明
     * 拿到用户及用户的角色、权限等信息
     */
    public static Claims getClaimsFromToken(String token) {
        Claims claims;
        try {
            //用密钥(必字节数组)解析jwt,获取body(有效载荷)
            claims = Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary("xiaosun123^.^")).parseClaimsJws(token).getBody();
        } catch (Exception e) {
            //解析不了,这个token就是无效的
            claims = null;
        }
        return claims;
    }

   
}

我们写个用户类用于测试

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class UserEntity {
    private Long id;
    private String username;
    private String password;
}

现在我们写主方法debug测试:


import com.example.demo.base.sp.dto.UserEntity;
import com.example.demo.base.utils.jwtUtils.JwtTokenUtils;
import io.jsonwebtoken.Claims;

import java.util.HashMap;
import java.util.Map;

public class Test {

    public static void main(String[] args) {
        UserEntity userEntity = new UserEntity();
        userEntity.setId(123L);
        userEntity.setUsername("王一");
        userEntity.setPassword("123456");
        Map<String,Object> cliams = new HashMap<>();
        cliams.put("user_name",userEntity.getUsername());
        cliams.put("user_password",userEntity.getPassword());
        final String accessToken = JwtTokenUtils.testGetAccessToken(userEntity.getId().toString(),cliams);
        System.out.println(accessToken);
        Claims newCliams = JwtTokenUtils.getClaimsFromToken(accessToken);
        final Long id = Long.valueOf(newCliams.getSubject());
        System.out.println(id);
    }
}

可以看出我们生成了一段三段式的token 

 接下来我们对token进行解析

 好了这样我们就完成了对账户密码的 加密解密


版权声明:本文为qq_38895905原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。