一、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";
@Override
public 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);
}
@Override
public int getOrder() {
return 3;
}
}
测试结果