一、JwtUtil 工具类
package com.changgou.system.utils;/*** @author :lijunxuan* @date :Created in 2019/7/11 17:14* @description :* @version: 1.0*/import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Date;/*** JWT工具类*/
public class JwtUtil {//有效期为public static final Long JWT_TTL = 3600000L;// 60 * 60 *1000 一个小时//设置秘钥明文public static final String JWT_KEY = "william";/*** 创建token* @param id* @param subject* @param ttlMillis* @return*/public static String createJWT(String id, String subject, Long ttlMillis) {//定义jwt签名的算法SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;//当前时间long nowMillis = System.currentTimeMillis();//将当前时间转换日期类型Date now = new Date(nowMillis);//将当前时间+超时时间if(ttlMillis==null){ttlMillis=JwtUtil.JWT_TTL;}long expMillis = nowMillis + ttlMillis;//将时间定义为date类型Date expDate = new Date(expMillis);//获取签名时候使用的密钥SecretKey secretKey = generalKey();JwtBuilder builder = Jwts.builder().setId(id) //唯一的ID.setSubject(subject) // 主题 可以是JSON数据.setIssuer("admin") // 签发者.setIssuedAt(now) // 签发时间.signWith(signatureAlgorithm, secretKey) //使用HS256对称加密算法签名, 第二个参数为秘钥.setExpiration(expDate);// 设置过期时间return builder.compact();}/*** 生成加密后的秘钥 secretKey* @return*/public static SecretKey generalKey() {byte[] encodedKey = Base64.getDecoder().decode(JwtUtil.JWT_KEY);SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");return key;}
}
二、创建过滤器,用于token验证
package com.william.filter;import com.william.util.JwtUtil;
import io.jsonwebtoken.Jwts;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;/*** @author :lijunxuan* @date :Created in 2019/7/11 17:39* @description :* @version: 1.0*//*** 鉴权过滤器* 判断用户是否有权限访问*/
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {//请求头中的令牌常量public final static String TOKEN = "token";@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//1.获取请求ServerHttpRequest request = exchange.getRequest();//2.获取响应ServerHttpResponse response = exchange.getResponse();//3.判断用户是否访问的为登录路径,如果是登录路径则放行if (request.getURI().getPath().contains("/admin/login")){return chain.filter(exchange);}//4. 获取请求头中的令牌HttpHeaders headers = request.getHeaders();String token = headers.getFirst(TOKEN);//5. 如果请求头中的令牌为空, 则返回错误状态码if (StringUtils.isEmpty(token)){response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}//6. 解析请求头中的jwt令牌try {JwtUtil.parseJWT(token);} catch (Exception e) {//7. 如果解析出错, 说明令牌过期或者被篡改, 返回状态码e.printStackTrace();response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}//8. 如果解析正常则放行return chain.filter(exchange);}@Overridepublic int getOrder() {return 3;}
}
测试结果