首页 > 编程知识 正文

jwt的token的使用流程,jwt的token机制原理

时间:2023-05-04 06:51:01 阅读:207993 作者:4003

    jwt(json web token)是一种能够允许我们在用户和服务器之间传递安全可靠信息的规范。它可以采用对称加密和非对称加密的方式,对我们所要传递的数据进行加密,防止数据的泄露。在web应用中,jwt通常可以结合Spring-security,对访问的页面进行安全保护,如果有需要,可以参照本文参考文献中的内容。本文主要对jwt的类进行封装,生成tocken信息。

    JWT 由三部分组成 头部(header)、荷载(payload) 、签名(signature)

    在使用Jwt时,我们首先在pom中引用jwt的lib

 

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

    然后,我们编写一个产生tocken 和获取tocken 的java通用类,也就是对jwt中的方法进行简单的封装

public class JWT { /** * 利用jwt生成token信息. * @param claims 数据声明(Claim)其实就是一个Map,比如我们想放入用户名, * 可以简单的创建一个Map然后put进去 * @param secret 用于进行签名的秘钥 * @return * @throws Exception */ public static String generateToken(Map<String, Object> claims,String secret) throws Exception { DESCoder desCoder = new DESCoder();        Key key = desCoder.toKey(secret);//设置过期时间为10分钟 Date ecpiration = new Date(System.currentTimeMillis()+600000L); return Jwts.builder() .setClaims(claims) .setExpiration(ecpiration) .signWith(SignatureAlgorithm.HS512, key) //采用什么算法是可以自己选择的,不一定非要采用HS512 .compact(); } /** * 利用jwt解析token信息. * @param token 要解析的token信息 * @param secret 用于进行签名的秘钥 * @return * @throws Exception */ public static Optional<Claims> getClaimsFromToken(String token,String secret) throws Exception { Claims claims; DESCoder desCoder = new DESCoder(); Key key = desCoder.toKey(secret); try { claims = Jwts.parser() .setSigningKey(key) .parseClaimsJws(token) .getBody(); return Optional.of(claims); } catch (Exception e) { return Optional.empty(); } } /** * 验证token是否过期 * @param tooken 要解析的token信息 * @param secret 用于进行签名的秘钥 * @return true 表示过期,false表示不过期,如果没有设置过期时间,则也不认为过期 * @throws Exception */ public static boolean isExpired(String tooken,String secret) throws Exception{ Optional<Claims> claims= getClaimsFromToken(tooken,secret); if(claims.isPresent()){ Date expiration = claims.get().getExpiration(); return expiration.before(new Date()) } return false; } /** * 获取tooken中的参数值 * @param tooken 要解析的token信息 * @param secret 用于进行签名的秘钥 * @return * @throws Exception */ public static Map<String,Object> extractInfo(String token,String secret) throws Exception{ Optional<Claims> claims = getClaimsFromToken(token,secret); if(claims.isPresent()){ Map<String,Object> info = new HashMap<String,Object>(); Set<String> keySet = claims.get().keySet(); //通过迭代,提取token中的参数信息 Iterator<String> iterator = keySet.iterator(); while(iterator.hasNext()){ String key = iterator.next(); Object value = claims.get().get(key); info.put(key,value); } return info; } return null; } }

    上述方法中的generateToken(Map<String, Object> claims,String secret)为产生token的方法,claims中为包含发送内容的map数据,方法中的SignatureAlgorithm.HS512 为加密算法,为对称加密,如果想使用非对称加密方法,需要改为RS256,同时,传入的key必须是公私钥,具体可参照“RS256加密JWT生成、验证”。signWith(SignatureAlgorithm.HS512, key)方法中的“key”可以为String类型,也可以为Key类型,如果我们在方法中传入keyd的类型为String时,signWith会自动将其转化为Key类型。上面方法中,我们直接传入String类型的secret为使用base64编码DES加密的String,大家如果觉得麻烦,可以直接输入String生成token,以及使用相同的string解密token信息,不需要看以下内容。

    上面中我们使用到的DESCoder类的内容为:

 

private Key toKey(byte[] key) throws Exception {DESKeySpec dks = new DESKeySpec(key);SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_ALGORTHM);SecretKey secretKey = keyFactory.generateSecret(dks);return secretKey;}/** * * @param key key(Base64编码) * @return * @throws Exception */public Key toKey(String key) throws Exception{ byte[] keyBytes = (new BASE64Decoder()).decodeBuffer(key); Key keyObj = toKey(keyBytes); return keyObj;}

 

    DES加密算法的生成方法为

 

import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectOutputStream;import java.security.Key;import java.security.SecureRandom;import java.util.Map;import javax.crypto.KeyGenerator;import sun.misc.BASE64Encoder;public class DESBuilder {/** 加密算法 */public static final String KEY_ALGORTHM = "DES";private Key key;/** * 构造函数. * * @param str * 传入的字符串,根据字符串随机生成Key */public DESBuilder(String str) {generatorRandomKey(str);}/** * @param strKey * 通过strKey生成随机Key */public void generatorRandomKey(String strKey) {try {KeyGenerator generator = KeyGenerator.getInstance(KEY_ALGORTHM);generator.init(new SecureRandom(strKey.getBytes()));this.key = generator.generateKey();generator = null;} catch (Exception e) {throw new RuntimeException("Error initializing SqlMap class. Cause: " + e);}}/** * @param strKey * 通过strKey生成Key * * @return Key对象 */public Key getKey() {return key;}/** * @param strKey * 通过strKey生成Key * * @return Key对象 */public String getKeyToString() {return (new BASE64Encoder()).encodeBuffer(key.getEncoded());}/** * @param filePath * 秘钥的存储路径(建议秘钥使用“.bat”后缀) * * @return 文件 */public void getKeyToFile(String keyAddress) {FileOutputStream fileOutput = null;ObjectOutputStream objectOutput = null;try {fileOutput = new FileOutputStream(keyAddress);objectOutput = new ObjectOutputStream(fileOutput);objectOutput.writeObject(this.key);System.out.println("success: " + keyAddress);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {fileOutput.close();objectOutput.close();} catch (IOException e) {e.printStackTrace();}}}}     至此,已经介绍完成jwt生成和解析token信息的方法,里面涉及到如何进行base64编码解码,如何生成用DES加解密以及Key类型数据的产生。

 

 

参考文献

 

1、JSON Web Token - 在Web应用间安全地传递信息

2、RS256加密JWT生成、验证

3、使用JWT保护你的Spring Boot应用 - Spring Security实战

4、使用JWT和Spring Security保护REST API

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。