gateway+jwtゲートウェイ認証
16049 ワード
考え方:グローバルフィルタはすべてのリクエストをブロックします(token有効期間を30分生成し、redisに入れて有効期間を3日間設定します.3日間などはリフレッシュインタフェースで自動的にリフレッシュでき、3日以上再ログインする必要があります).
フロントエンドはインタフェースを呼び出す前にtokenが期限切れかどうかを判断し(3 o分)、期限切れになったらインタフェースをリフレッシュし、新しいtokenを取り替え、
1-関連jarの導入
2-Jwtツールクラスの作成(token+解析tokenの生成)
4-関連インタフェースAPIの作成
転載先:https://www.cnblogs.com/domi22/p/10524005.html
フロントエンドはインタフェースを呼び出す前にtokenが期限切れかどうかを判断し(3 o分)、期限切れになったらインタフェースをリフレッシュし、新しいtokenを取り替え、
1-関連jarの導入
org.springframework.cloud
spring-cloud-starter-gateway
io.jsonwebtoken
jjwt
0.9.0
2-Jwtツールクラスの作成(token+解析tokenの生成)
package spring.cloud.gateway.common;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import io.jsonwebtoken.ExpiredJwtException;
import org.springframework.util.StringUtils;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
public class JwtUtil {
public static final String SECRET = "qazwsx123444$#%#()*&& asdaswwi1235 ?;!@#kmmmpom in***xx**&";
public static final String TOKEN_PREFIX = "Bearer";
public static final String LOGIN_URL = "/token/userId/pwd";
public static final String LOGOUT_URL = "/token/userId";
public static final String HEADER_AUTH = "authorization";
public static final String HEADER_USERID = "userid";
//token
public static final int TOKEN_EXPIRATION_MINUTE = 30;
//token redis
public static final int TOKEN_REDIS_EXPIRATION_DAY = 7;
public static String generateToken(String userId) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, TOKEN_EXPIRATION_MINUTE); //
Date date = calendar.getTime();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
df.format(date);
//todo token
HashMapmap = new HashMap<>();
map.put(HEADER_USERID, userId);
String jwt = Jwts.builder()
.setSubject(HEADER_USERID).setClaims(map)
.setExpiration(date)
.signWith(SignatureAlgorithm.HS512, SECRET)
.compact();
return TOKEN_PREFIX + " " + jwt;
}
public static MapvalidateToken(String token) {
HashMaptokenMap = new HashMap ();
if (StringUtils.isEmpty(token)) {
return tokenMap;
}
try {
MaptokenBody = Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
.getBody();
String userId = String.valueOf(tokenBody.get(HEADER_USERID));
tokenMap.put(HEADER_USERID, userId);
}catch (ExpiredJwtException e){
e.printStackTrace();
}
return tokenMap;
}
/**
* jwtUtil
*
* @param token
* @return
*/
public static MapvalidateTokenAndUser(String token, String userIdIn) {
MaptokenResultMap = new HashMap<>();
if (StringUtils.isEmpty(token) || StringUtils.isEmpty(userIdIn)) {
return tokenResultMap;
}
tokenResultMap = validateToken(token);
if (StringUtils.isEmpty(token) || StringUtils.isEmpty(userIdIn)) {
return tokenResultMap;
}
// userid token
String userIdOri = tokenResultMap.get(HEADER_USERID);
if (!userIdIn.equals(userIdOri)) {
return new HashMap();
}
return tokenResultMap;
}
}
3- 编写过滤器类
package spring.cloud.gateway.filter;
import java.net.URI;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.PathContainer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import spring.cloud.gateway.common.JwtUtil;
import spring.cloud.gateway.exception.PermissionException;
/**
* https://blog.csdn.net/tianyaleixiaowu/article/details/83375246
* response https://bbs.csdn.net/topics/392412604?list=11074255
*/
@Component
public class AuthFilter implements GlobalFilter {
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
HttpHeaders header = request.getHeaders();
HttpMethod method = request.getMethod();
String token = header.getFirst(JwtUtil.HEADER_AUTH);
String userId = header.getFirst(JwtUtil.HEADER_USERID);
PathContainer pathContainer = request.getPath().pathWithinApplication();
String path = pathContainer.value();
//2-
if (StringUtils.isBlank(token)) {
// ,
if (path.contains(JwtUtil.LOGIN_URL) && HttpMethod.POST.equals(method)) {
throw new PermissionException("please login");
}
return chain.filter(exchange);
}
//3- token
if (path.indexOf("refresh") >= 0) {
// ( userId token )
return chain.filter(exchange);
}
//4- token
if (path.contains(JwtUtil.LOGOUT_URL) && HttpMethod.DELETE.equals(method)) {
// ( userId token )
return chain.filter(exchange);
}
//5- token
Map validateResultMap = JwtUtil.validateTokenAndUser(token, userId);
if (validateResultMap == null || validateResultMap.isEmpty()) {
throw new PermissionException("token ");
}
// TODO header
Route gatewayUrl = exchange.getRequiredAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
URI uri = gatewayUrl.getUri();
// SPRING-CLOUD-SERVICE SPRING-CLOUD-GATEWAY
String serviceName = uri.getHost();
ServerHttpRequest.Builder mutate = request.mutate();
mutate.header("x-user-id", validateResultMap.get("userid"));
mutate.header("x-user-name", validateResultMap.get("user"));
mutate.header("x-user-serviceName", serviceName);
ServerHttpRequest buildReuqest = mutate.build();
//todo , response header
//ServerHttpResponse response = exchange.getResponse();
//response.getHeaders().add("new_token","token_value");
return chain.filter(exchange.mutate().request(buildReuqest).build());
}
}
4-関連インタフェースAPIの作成
package spring.cloud.gateway.controller;
import org.springframework.web.bind.annotation.*;
import spring.cloud.gateway.common.JwtUtil;
import java.util.Map;
@RestController
@RequestMapping("/token")
public class TokenController {
/**
*
* @param user(userID +pwd)
* @return
*/
@PostMapping("/userId/pwd")
public String getToken(@RequestBody Map user) {
//
String result = "";
if (user == null || user.isEmpty()) {
return result;
}
String userId = user.get("userId");
String pwd = user.get("pwd");
if (!doLogin(userId,pwd)) {
return result;
}
String token = JwtUtil.generateToken(userId);
// todo token redis , 2 * t
return token;
}
private Boolean doLogin(String userId,String pwd) {
// user
if ("admin".equals(userId) && "123".equals(pwd)) {
return true;
}
if ("spring".equals(userId) && "123".equals(pwd)) {
return true;
}
if ("gateway".equals(userId) && "123".equals(pwd)) {
return true;
}
return false;
}
/**
*
*/
/**
* token
* userId token
*/
}
転載先:https://www.cnblogs.com/domi22/p/10524005.html