MSA 학습(6) - API-Gateway에서 인증관리

엉무개·2021년 8월 27일
0

MSA

목록 보기
7/12

1. JWT 관련 라이브러리 추가

//    jwt
    implementation 'io.jsonwebtoken:jjwt-api:0.11.2'
    implementation 'io.jsonwebtoken:jjwt-impl:0.11.2'
    implementation 'io.jsonwebtoken:jjwt-jackson:0.11.2'

2. JWTUtil 클래스 작성


public class JWTUtil {
    private String secretKey="2dkfgn5mldddpwl3mrmwkdfm448fkcms932kdfkdm4m4meddkskdsmfmdkk4kk3kk4k3";

    private long expire = 60 * 24 * 30;

//    JWT 토큰 생성
    public String generateToken(String content) throws Exception {
        return Jwts.builder()
                .setIssuedAt(new Date())
                .setExpiration(Date.from(ZonedDateTime.now().plusMinutes(expire).toInstant()))
                .claim("sub",content)
                .signWith(SignatureAlgorithm.HS256,secretKey.getBytes(StandardCharsets.UTF_8))
                .compact();
    }

    public String validateAndExtract(String tokenStr){
        String contentValue = null;
        try {
            DefaultJws defaultJws = (DefaultJws) Jwts.parser()
                    .setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8))
                    .parseClaimsJws(tokenStr);

            DefaultClaims claims = (DefaultClaims) defaultJws.getBody();

            contentValue = claims.getSubject();
        } catch (Exception ex){
            ex.printStackTrace();
            contentValue = null;
        }
        return contentValue;
    }
}

3. filter 패키지에 CustAuthFilter 작성


@Component
public class CustomAuthFilter extends AbstractGatewayFilterFactory<CustomAuthFilter.Config> {
    public CustomAuthFilter() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return ((exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();

            // Request Header 에 token 이 존재하지 않을 때
            if (!request.getHeaders().containsKey(HttpHeaders.AUTHORIZATION)) {
                return handleUnAuthorized(exchange); // 401 Error
            }

            // Request Header 에서 token 문자열 받아오기
            List<String> token = request.getHeaders().get(HttpHeaders.AUTHORIZATION);
            String tokenString = Objects.requireNonNull(token).get(0);
            tokenString = tokenString.replace("Bearer", "").trim();

            // 토큰 검증
            if (new JWTUtil().validateAndExtract(tokenString) == null) {
                return handleUnAuthorized(exchange); // 토큰이 일치하지 않을 때
            }

            return chain.filter(exchange); // 토큰이 일치할 때

        });
    }

    private Mono<Void> handleUnAuthorized(ServerWebExchange exchange) {
        ServerHttpResponse response = exchange.getResponse();

        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        return response.setComplete();
    }

    public static class Config {

    }
}

4. application.yml에서 필요 마이크로 서비스에 filter 추가

spring:
  application:
    name: apigateway-service
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/user-service/**
        - id: product-service
          uri: lb://PRODUCT-SERVICE
          predicates:
            - Path=/product-service/**
          filters:
            - CustomAuthFilter

5. 토큰 없이 데이터 요청 시

  • 401에러

6. 올바른 토큰을 가지고 데이터 요청

  • 200응답
profile
엉덩이가 무거운 개발자

0개의 댓글