Skip to content

Commit cf39e7d

Browse files
committed
Feat: 토큰 인증 방식 수정
1 parent 19cdb54 commit cf39e7d

6 files changed

Lines changed: 68 additions & 85 deletions

File tree

build.gradle.kts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,6 @@ dependencies {
3232
implementation("org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j")
3333
implementation("org.springframework.cloud:spring-cloud-starter-gateway")
3434

35-
// JWT
36-
implementation("io.jsonwebtoken:jjwt-api:0.12.6")
37-
runtimeOnly("io.jsonwebtoken:jjwt-impl:0.12.6")
38-
runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.12.6")
39-
4035
compileOnly("org.projectlombok:lombok")
4136
annotationProcessor("org.projectlombok:lombok")
4237
testImplementation("org.springframework.boot:spring-boot-starter-test")
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package flipnote.apigateway.client;
2+
3+
import org.springframework.beans.factory.annotation.Value;
4+
import org.springframework.stereotype.Component;
5+
import org.springframework.web.reactive.function.client.WebClient;
6+
import reactor.core.publisher.Mono;
7+
8+
@Component
9+
public class TokenValidationClient {
10+
11+
private final WebClient webClient;
12+
13+
public TokenValidationClient(@Value("${app.user-service.url}") String userServiceUrl) {
14+
this.webClient = WebClient.builder()
15+
.baseUrl(userServiceUrl)
16+
.build();
17+
}
18+
19+
public Mono<TokenValidationResponse> validateToken(String token) {
20+
return webClient.post()
21+
.uri("/v1/auth/token/validate")
22+
.bodyValue(new TokenValidationRequest(token))
23+
.retrieve()
24+
.bodyToMono(TokenValidationResponse.class);
25+
}
26+
27+
public record TokenValidationRequest(String token) {}
28+
29+
public record TokenValidationResponse(Long userId, String email, String role) {}
30+
}

src/main/java/flipnote/apigateway/filter/AuthenticationFilter.java

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
package flipnote.apigateway.filter;
22

3-
import flipnote.apigateway.util.JwtUtil;
4-
import io.jsonwebtoken.Claims;
5-
import io.jsonwebtoken.JwtException;
3+
import flipnote.apigateway.client.TokenValidationClient;
64
import lombok.extern.slf4j.Slf4j;
75
import org.springframework.cloud.gateway.filter.GatewayFilter;
86
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
9-
import org.springframework.http.HttpHeaders;
7+
import org.springframework.http.HttpCookie;
108
import org.springframework.http.HttpStatus;
119
import org.springframework.stereotype.Component;
1210
import org.springframework.web.server.ServerWebExchange;
@@ -16,47 +14,45 @@
1614
@Component
1715
public class AuthenticationFilter extends AbstractGatewayFilterFactory<AuthenticationFilter.Config> {
1816

19-
private final JwtUtil jwtUtil;
17+
private final TokenValidationClient tokenValidationClient;
2018

21-
public AuthenticationFilter(JwtUtil jwtUtil) {
19+
public AuthenticationFilter(TokenValidationClient tokenValidationClient) {
2220
super(Config.class);
23-
this.jwtUtil = jwtUtil;
21+
this.tokenValidationClient = tokenValidationClient;
2422
}
2523

24+
private static final String ACCESS_TOKEN_COOKIE = "accessToken";
25+
2626
@Override
2727
public GatewayFilter apply(Config config) {
2828
return (exchange, chain) -> {
29-
String authHeader = exchange.getRequest().getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
29+
HttpCookie cookie = exchange.getRequest().getCookies().getFirst(ACCESS_TOKEN_COOKIE);
3030

31-
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
32-
log.warn("Missing or invalid Authorization header");
31+
if (cookie == null) {
32+
log.warn("Missing access token cookie");
3333
return onError(exchange, HttpStatus.UNAUTHORIZED);
3434
}
3535

36-
String token = authHeader.substring(7);
37-
38-
try {
39-
Claims claims = jwtUtil.parseToken(token);
40-
41-
Long userId = jwtUtil.getUserId(claims);
42-
String email = jwtUtil.getEmail(claims);
43-
String role = jwtUtil.getRole(claims);
36+
String token = cookie.getValue();
4437

45-
log.debug("Authenticated user: id={}, email={}, role={}", userId, email, role);
38+
return tokenValidationClient.validateToken(token)
39+
.flatMap(response -> {
40+
log.debug("Authenticated user: id={}, email={}, role={}",
41+
response.userId(), response.email(), response.role());
4642

47-
ServerWebExchange modifiedExchange = exchange.mutate()
48-
.request(r -> r
49-
.header("X-User-Id", String.valueOf(userId))
50-
.header("X-User-Email", email)
51-
.header("X-User-Role", role))
52-
.build();
43+
ServerWebExchange modifiedExchange = exchange.mutate()
44+
.request(r -> r
45+
.header("X-User-Id", String.valueOf(response.userId()))
46+
.header("X-User-Email", response.email())
47+
.header("X-User-Role", response.role()))
48+
.build();
5349

54-
return chain.filter(modifiedExchange);
55-
56-
} catch (JwtException e) {
57-
log.error("JWT validation failed: {}", e.getMessage());
58-
return onError(exchange, HttpStatus.UNAUTHORIZED);
59-
}
50+
return chain.filter(modifiedExchange);
51+
})
52+
.onErrorResume(e -> {
53+
log.error("Token validation failed: {}", e.getMessage());
54+
return onError(exchange, HttpStatus.UNAUTHORIZED);
55+
});
6056
};
6157
}
6258

src/main/java/flipnote/apigateway/util/JwtUtil.java

Lines changed: 0 additions & 45 deletions
This file was deleted.

src/main/resources/application-local.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ spring:
1818
- /v1/auth/login
1919
- /v1/auth/register
2020
- /v1/auth/token/refresh
21+
- /v1/auth/token/validate
2122
- /v1/auth/email-verification/request
2223
- /v1/auth/email-verification
2324
- /v1/auth/password-reset/request
@@ -35,8 +36,11 @@ spring:
3536
- /v1/auth/social-links
3637
- /v1/auth/social-links/*
3738
- /v1/oauth2/authorization/*
39+
- /v1/oauth2/links/*
40+
3841
filters:
3942
- AuthenticationFilter
4043

41-
jwt:
42-
secret: "55ca298dcfc216e215622e3f48a251abaa4e8bb973074f065ab170e311acc15811d01a2407290c3ac143648196306d4a6f666a4ed364d3df633e08eb184bb0aea0f2edde4fd2d7fa68ea95ddbc421ff532ce47bde775975911042d665bc22d88a9fa26a03bb4d25530b8cdeb1247d87c9e3efcd721e368b0566b00a43308a729"
44+
app:
45+
user-service:
46+
url: http://localhost:8081

src/main/resources/application.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ spring:
2828
- /v1/auth/login
2929
- /v1/auth/register
3030
- /v1/auth/token/refresh
31+
- /v1/auth/token/validate
3132
- /v1/auth/email-verification/request
3233
- /v1/auth/email-verification
3334
- /v1/auth/password-reset/request
@@ -46,6 +47,7 @@ spring:
4647
- /v1/auth/social-links/*
4748
- /v1/oauth2/authorization/*
4849
- /v1/oauth2/links/*
50+
4951
filters:
5052
- AuthenticationFilter
5153

@@ -61,8 +63,9 @@ spring:
6163
filters:
6264
- AuthenticationFilter
6365

64-
jwt:
65-
secret: ${JWT_SECRET}
66+
app:
67+
user-service:
68+
url: http://user-service:8081
6669

6770
management:
6871
endpoints:

0 commit comments

Comments
 (0)