JWT操作工具类分享
生活随笔
收集整理的這篇文章主要介紹了
JWT操作工具类分享
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
分享個(gè)人操作的JWT的工具類,基于jjwt庫,這是Java圈子中最流行的JWT操作庫。
文章目錄
- 一、應(yīng)用場景
- 二、實(shí)戰(zhàn)案例
- 1. jjwt 開源地址
- 2. 加依賴
- 3. 工具類
- 4. 寫配置
- 5. 使用
- 三、企業(yè)需求
一、應(yīng)用場景
給用戶不敏感信息生成token,作為用戶登陸的唯一標(biāo)識,訪問后端都必須攜帶token,也就是說,后端處理前端請求時(shí)會(huì)先判斷token是否合法,不合法直接響應(yīng)狀態(tài)碼;合法正常處理請求。
前后端分離項(xiàng)目采用session 和cookie即可,前后端分離場景:建議采用token,因?yàn)橛辛丝缬騿栴}。
二、實(shí)戰(zhàn)案例
1. jjwt 開源地址
GIthub:https://github.com/jwtk/jjwt
2. 加依賴
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.11.1</version></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.11.1</version><scope>runtime</scope></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred --><version>0.11.1</version><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version><scope>provided</scope></dependency><!-- https://mvnrepository.com/artifact/commons-codec/commons-codec --><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.14</version></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>20.0</version></dependency>3. 工具類
package com.itmuch.usercenter.util;import com.google.common.collect.Maps; import io.jsonwebtoken.*; import io.jsonwebtoken.security.Keys; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Base64; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component;import javax.crypto.SecretKey; import java.util.Date; import java.util.HashMap; import java.util.Map;@Slf4j @RequiredArgsConstructor @SuppressWarnings("WeakerAccess") @Component public class JwtOperator {/*** 秘鑰* - 默認(rèn)aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrsssttt*/@Value("${secret:aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrsssttt}")private String secret;/*** 有效期,單位秒* - 默認(rèn)2周*/@Value("${expire-time-in-second:1209600}")private Long expirationTimeInSecond;/*** 從token中獲取claim** @param token token* @return claim*/public Claims getClaimsFromToken(String token) {try {return Jwts.parser().setSigningKey(this.secret.getBytes()).parseClaimsJws(token).getBody();} catch (ExpiredJwtException | UnsupportedJwtException | MalformedJwtException | IllegalArgumentException e) {log.error("token解析錯(cuò)誤", e);throw new IllegalArgumentException("Token invalided.");}}/*** 獲取token的過期時(shí)間** @param token token* @return 過期時(shí)間*/public Date getExpirationDateFromToken(String token) {return getClaimsFromToken(token).getExpiration();}/*** 判斷token是否過期** @param token token* @return 已過期返回true,未過期返回false*/private Boolean isTokenExpired(String token) {Date expiration = getExpirationDateFromToken(token);return expiration.before(new Date());}/*** 計(jì)算token的過期時(shí)間** @return 過期時(shí)間*/public Date getExpirationTime() {return new Date(System.currentTimeMillis() + this.expirationTimeInSecond * 1000);}/*** 為指定用戶生成token** @param claims 用戶信息* @return token*/public String generateToken(Map<String, Object> claims) {Date createdTime = new Date();Date expirationTime = this.getExpirationTime();byte[] keyBytes = secret.getBytes();SecretKey key = Keys.hmacShaKeyFor(keyBytes);return Jwts.builder().setClaims(claims).setIssuedAt(createdTime).setExpiration(expirationTime)// 你也可以改用你喜歡的算法// 支持的算法詳見:https://github.com/jwtk/jjwt#features.signWith(key, SignatureAlgorithm.HS256).compact();}/*** 判斷token是否非法** @param token token* @return 未過期返回true,否則返回false*/public Boolean validateToken(String token) {return !isTokenExpired(token);}// public static void main(String[] args) { // // 1. 初始化 // JwtOperator jwtOperator = new JwtOperator(); // jwtOperator.expirationTimeInSecond = 1209600L; // jwtOperator.secret = "aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrsssttt"; // // // 2.設(shè)置用戶信息 // HashMap<String, Object> objectObjectHashMap = Maps.newHashMap(); // objectObjectHashMap.put("id", "1"); // // // 測試1: 生成token // String token = jwtOperator.generateToken(objectObjectHashMap); // // 會(huì)生成類似該字符串的內(nèi)容: eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjEiLCJpYXQiOjE1NjU1ODk4MTcsImV4cCI6MTU2Njc5OTQxN30.27_QgdtTg4SUgxidW6ALHFsZPgMtjCQ4ZYTRmZroKCQ // System.out.println(token); // // // 將我改成上面生成的token!!! // String someToken = "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjEiLCJpYXQiOjE1NjU1OTQ1NjIsImV4cCI6MTU2NjgwNDE2Mn0.PAvWPcQAZnSlYKNbZr4O1l9aA4LPphuq0OG2QIs7O5E\n"; // // 測試2: 如果能token合法且未過期,返回true // Boolean validateToken = jwtOperator.validateToken(someToken); // System.out.println(validateToken); // // // 測試3: 獲取用戶信息 // Claims claims = jwtOperator.getClaimsFromToken(someToken); // System.out.println(claims); // // // 將我改成你生成的token的第一段(以.為邊界) // String encodedHeader = "eyJhbGciOiJIUzI1NiJ9"; // // 測試4: 解密Header // byte[] header = Base64.decodeBase64(encodedHeader.getBytes()); // System.out.println(new String(header)); // // // 將我改成你生成的token的第二段(以.為邊界) // String encodedPayload = "eyJpZCI6IjEiLCJpYXQiOjE1NjU1ODk1NDEsImV4cCI6MTU2Njc5OTE0MX0"; // // 測試5: 解密Payload // byte[] payload = Base64.decodeBase64(encodedPayload.getBytes()); // System.out.println(new String(payload)); // // // 測試6: 這是一個(gè)被篡改的token,因此會(huì)報(bào)異常,說明JWT是安全的 // jwtOperator.validateToken("eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjEiLCJpYXQiOjE1NjU1ODk3MzIsImV4cCI6MTU2Njc5OTMzMn0.nDv25ex7XuTlmXgNzGX46LqMZItVFyNHQpmL9UQf-aUxxx"); // } }4. 寫配置
jwt:secret: aaaaaaabbbbbbcccccdddddaaaaaaabbbbbbcccccdddddaaaaaaabbbbbbcccccddddd# 有效期,單位秒,默認(rèn)2周expire-time-in-second: 12096005. 使用
@Autowiredprivate final JwtOperator jwtOperator;三、企業(yè)需求
1.首先寫一個(gè)攔截器,攔截前端的所有請求
2.獲取請求頭部header中的token是否合法
1>合法正常處理請求
2>不合法拋出自定義異常和狀態(tài)碼
問題1:
為什么是自定義異常?
釋義:
由于不能講控制臺的異常直接拋出到前端頁面,這樣不友好,定義全局異常處理類,根據(jù)需求自定義異常信息和狀態(tài)碼。
例如:token不合法,狀態(tài)碼是401
總結(jié)
以上是生活随笔為你收集整理的JWT操作工具类分享的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分布式Session解决方案_Token
- 下一篇: Mybatis-Plus的SQL语句组拼