用户通过网关进行登录,网关过滤器进行判断,如果时登录则由路由到后台管理微服务进行登录。
用户登录成功后后台管理服务器发送Token 信息返回给用户。
用户拿到Token信息,再次访问网关,网管过滤器接收用户带着Token信息。
网管过滤器解析Token,判断是否有权限,如果有就放行,如果没有则返回未认证。
第一步导入依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
第二部使用Jwt工具类
public class JwtUtil {
//有效期为
public static final Long JWT_TTL = 3600000L;// 60 * 60 *1000 一个小时
//设置秘钥明文
public static final String JWT_KEY = "itcast";
/**
* 创建token
* @param id
* @param subject
* @param ttlMillis
* @return
*/
public static String createJWT(String id, String subject, Long ttlMillis) {
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 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;
}
/**
* 解析
*
* @param jwt
* @return
* @throws Exception
*/
public static Claims parseJWT(String jwt) throws Exception {
SecretKey secretKey = generalKey();
return Jwts.parser()
.setSigningKey(secretKey)
.parseClaimsJws(jwt)
.getBody();
}
}
在网关中配置一个全局的
/**
* @author 杜兰特
* @version 1.0
* @description TODO
* @date 2023/3/1 10:49
*/
@Component
@Order(-1)
public class TokenFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//todo 获取请求和响应
ServerHttpResponse response = exchange.getResponse();
ServerHttpRequest request = exchange.getRequest();
//todo 判断请求是否成功(不是登录请求 从请求头中获取令牌)
if (request.getURI().getPath().contains("/admin/login")){
return chain.filter(exchange);
}
//todo 获取请求头
HttpHeaders headers = request.getHeaders();
//todo 请求成功登录请求
String token = headers.getFirst("token");
//todo 判断请求头中是否有令牌
if (StringUtils.isBlank(token)){
//todo 响应中放入返回的状态吗, 没有权限访问
response.setStatusCode(HttpStatus.UNAUTHORIZED);//返回401
return response.setComplete();
}
//todo 如果请求头中有令牌则解析令牌
try {
Claims claims = JwtUtil.parseJWT(token);
} catch (Exception e) {
e.printStackTrace();
//todo 解析jwt令牌出错, 说明令牌过期或者伪造等不合法情况出现
response.setStatusCode(HttpStatus.UNAUTHORIZED);//返回401
return response.setComplete();
}
//todo 校验成功 放行
return chain.filter(exchange);
}
}