티스토리 뷰
- 코드를 원하시는 분은 하단에 코드를 첨부하니 확인해주세요.
JWT 토큰을 생성하는 법을 알아봤으니 이제 해당 토큰을 활용해서 인증을 받는 기능을 구현하고자 합니다.
마찬가지로 pom.xml에 JJWT의 Dependency를 추가해줍니다.
#pom.xml
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
jjwt는 Jwt사용에 있어서 필수적인 요소인데 이를 인증하기 위해서는 jaxb-api가 필요합니다. 해당 dependency가 없으면 오류가 발생하는데 이는 올바른 응답을 위해서 반드시 요청에 Converter가 필요하다 정도로 생각하면 될 거 같습니다.
다음으로는 AuthorizationHeaderFilter.Class를 생성하고 다음과 같이 입력합니다. 약간의 주석이 달려있으니 참고하시면 좋을 것 같습니다.
#AuthorizationHeaderFilter.java
package com.example.apigatewayservice.filter;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.env.Environment;
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.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
@Slf4j
public class AuthorizationHeaderFilter extends AbstractGatewayFilterFactory<AuthorizationHeaderFilter.Config> {
Environment env;
@Autowired
public AuthorizationHeaderFilter(Environment env){
// 부모 클래스의 Config 설정을 그대로 가져오는 것은 반드시 선행되어야 함.
super(Config.class);
this.env = env;
}
//추후에 작성할 Config 클래스
public static class Config{
}
// Override
/*
* 1. 해당 필터는 Jwt 토큰을 인증하는 과정을 거칩니다.
* 2. 기본적으로 토큰정보 확인 하는 과정 후 인증완료의 메커니즘 입니다.
* 3. login -> token -> users (with token) -> header(include token) 안에 token 정보가 있습니다.
*/
@Override
public GatewayFilter apply(Config config) {
return ((exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
// 해당 IF문은 인증 실패 시 에러처리 하는 문구입니다.
if(!request.getHeaders().containsKey(HttpHeaders.AUTHORIZATION)){
return onError(exchange,"no authorization header", HttpStatus.UNAUTHORIZED);
}
String authorizationHeader = request.getHeaders().get(org.springframework.http.HttpHeaders.AUTHORIZATION).get(0);
// Bearer 방식으로 토큰인증을 진행하기에 토큰 머리쪽에 Bearer가 붙어서 옵니다. 해당 토큰에서 Bearer를 삭제하는 과정입니다.
String jwt = authorizationHeader.replace("Bearer","");
// 최종적으로 유효한 토큰인지 체크 합니다. 유효한 토큰이 아니라면 onError를 리턴하고 해당 URL에 접근을 막습니다.
if(!isJwtValid(jwt)){
return onError(exchange,"JWT token is not vaild", HttpStatus.UNAUTHORIZED);
}
return chain.filter(exchange);
});
}
//JWT 유효성 체크
private boolean isJwtValid(String jwt) {
boolean returnValue = true;
String subject = null;
try {
// 토큰의 Parse과정을 통해서 유효성을 체크합니다. 기본적으로
// Body 안의 sub라는 항목이 있는지 체크합니다.
subject = Jwts.parser().setSigningKey(env.getProperty("token.secret"))
.parseClaimsJws(jwt).getBody()
.getSubject();
}catch(Exception ex){
returnValue = false;
}
if (subject == null || subject.isEmpty()){
returnValue = false;
}
//returnValue를 리턴합니다 해당 값이 true 냐 false 따라서 접근 여부를 결정할 예정입니다.
return returnValue;
}
// Mono, Flux -> Spring WebFlux
private Mono<Void> onError(ServerWebExchange exchange, String err, HttpStatus httpStatus) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(httpStatus);
log.error(err);
//Mono타입으로 전달할 수 있는 함수
return response.setComplete();
}
}
마지막으로 application.yml을 수정해줍니다.
#application.yml
Login 과 회원등록은 인증이 필요한 Url이 아니기에 그대로 두고, 나머지 조회기능을 가진 기능들은
인증 후에 접속이 가능하도록 설정을 해줍니다.
- id: user-service
uri: lb://USER-SERVICE
predicates:
- Path=/user-service/**
- Method=GET
filters:
- RemoveRequestHeader=Cookie
- RewritePath=/user-service/(?<segment>.*),/$\{segment}
- AuthorizationHeaderFilter
마지막으로 해당 Gateway 에서도 동일한 토큰을 발급해줍니다.
token:
secret: ggpark_token
여기까지 진행하면 토큰을 인증하는 과정은 끝났습니다. 그럼 해당 토큰을 활용해 인증하는 과정을 POST-MAN으로
진행하면 끝입니다.
실행할 서비스 목록입니다.
Ecommerce-Service ( Eureka-Server )
Gateway-Service
User-Service
#Test Case ( 회원 등록 )
먼저 기존에 만들어둔 User-Service 에서 회원 등록을 활용해서 등록을 진행해줍니다.
#Test Case ( 로그인 & 토큰 확인 )
그리고 Login을 통해서 발급받은 토큰을 확인합니다. Headers 최상단에 있습니다. 복사해주세요.
#Test Case ( 토큰 인증 )
먼저 토큰값으로 인증해야하는지 테스트를 하기 위해서 No Auth 로 /user-service/welcome 으로 접속해봅시다.
401Error가 출력된다면 정상적으로 인증 시스템이 가동중입니다.
그리고 저희가 사용할 방식은 Bearer Token 입니다. 해당 값으로 맞춰준 뒤 복사한 토큰값을 붙혀넣고 다시 요청을
Send 합니다. 200OK와 함께 Greeting Message 가 잘 출력된다면 성공입니다.
감사합니다.
- 아래에 해당 프로젝트를 첨부합니다. 감사합니다.
'웹 프로그래밍 > MSA 학개론' 카테고리의 다른 글
[MSA] User-Service와 Config Server 연동 - 1 - (0) | 2022.04.21 |
---|---|
[MSA] Spring Cloud Config 핥아먹기 (0) | 2022.04.21 |
[MSA] JWT 토큰 생성 (0) | 2022.04.20 |
[MSA] 잠시 쉬어가는 MSA (RewritePath) (0) | 2022.04.19 |
[MSA] Spring Cloud로 개발하는 E-commerce 마이크로 서비스 어플리케이션(Orders) - 7 - (0) | 2022.04.19 |
- Total
- Today
- Yesterday
- MSA
- 미래의나에게동기부여
- github
- consumer
- 운동
- producer
- docker
- 루틴기록
- kafka
- ACTUATOR
- zipkin
- LoadBalancer
- prometheus
- Logstash to ElasticSearch
- JWT
- springcloud
- config
- elasticSearch
- MariaDB
- Kafka Connect
- 오늘저녁 삼겹살
- 빅-오
- git
- Gateway
- Feign
- Logstash 활용
- rabbitmq
- 운동일기
- UserService
- Spring + ELK
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |