JWTtoken 微服务登录安全验证
1、添加maven 依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.7.0</version>
</dependency>
二 编写工具类
public class JWTUtil {
public static final String SECRET_KEY = "123456";
public static final long TOKEN_EXPIRE_TIME = 5 * 60 * 1000;
public static final long REFRESH_TOKEN_EXPIRE_TIME = 10 * 60 * 1000;
private static final String ISSUER = "issuer";
public static String generateToken(String username){
Date now = new Date();
Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);
String token = JWT.create()
.withIssuer(ISSUER)
.withIssuedAt(now)
.withExpiresAt(new Date(now.getTime() + TOKEN_EXPIRE_TIME))
.withClaim("username", username)
.sign(algorithm);
return token;
}
public static boolean verify(String token){
try {
Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);
JWTVerifier verifier = JWT.require(algorithm)
.withIssuer(ISSUER)
.build();
verifier.verify(token);
return true;
} catch (Exception ex){
ex.printStackTrace();
}
return false;
}
public static String getUsername(String token){
try{
return JWT.decode(token).getClaim("username").asString();
}catch(Exception ex){
ex.printStackTrace();
}
return "";
}
}
3 登录业务实现
@RestController
public class LoginController {
@Autowired
StringRedisTemplate redisTemplate;
@GetMapping("/login")
public AuthResult login(@RequestParam String username, @RequestParam String password) {
if("admin".equals(username) && "admin".equals(password)){
String token = JWTUtil.generateToken(username);
String refreshToken = StringUtil.getUUIDString();
redisTemplate.opsForHash().put(refreshToken, "token", token);
redisTemplate.opsForHash().put(refreshToken, "username", username);
redisTemplate.expire(refreshToken, JWTUtil.REFRESH_TOKEN_EXPIRE_TIME, TimeUnit.MILLISECONDS);
return new AuthResult(0, "success", token, refreshToken);
}else{
return new AuthResult(1001, "username or password error");
}
}
@GetMapping("/refreshToken")
public AuthResult refreshToken(@RequestParam String refreshToken) {
String username = (String)redisTemplate.opsForHash().get(refreshToken, "username");
if(StringUtil.isEmpty(username)){
return new AuthResult(1003, "refreshToken error");
}
String newToken = JWTUtil.generateToken(username);
redisTemplate.opsForHash().put(refreshToken, "token", newToken);
return new AuthResult(0, "success", newToken, refreshToken);
}
@GetMapping("/")
public String index() {
return "auth-service: " + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
}
4 创建全局的网关过滤器
@Component
public class JWTAuthFilter implements GlobalFilter, Ordered{
@Override
public int getOrder() {
return -100;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String url = exchange.getRequest().getURI().getPath();
if(url.indexOf("/auth-service/") >= 0){
return chain.filter(exchange);
}
String token = exchange.getRequest().getHeaders().getFirst("Authorization");
if(StringUtil.isEmpty(token)){
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.OK);
response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
Response res = new Response(401, "401 unauthorized");
byte[] responseByte = JSONObject.fromObject(res).toString().getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = response.bufferFactory().wrap(responseByte);
return response.writeWith(Flux.just(buffer));
}
boolean verifyResult = JWTUtil.verify(token);
if(!verifyResult){
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.OK);
response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
Response res = new Response(1004, "invalid token");
byte[] responseByte = JSONObject.fromObject(res).toString().getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = response.bufferFactory().wrap(responseByte);
return response.writeWith(Flux.just(buffer));
}
return chain.filter(exchange);
}
}