Skip to content

Commit b795eb8

Browse files
committed
feat: 로그아웃 체크 필터 생성
- AS-IS: 액세스 토큰을 검증하면서 로그아웃했는지를 검증하고 있다. 이는 액세스 토큰의 검증부에 들어갈 것이 아니라, 더 이전 단계에서 처리되어야 한다. - TO-BE: 로그아웃 토큰을 필터에서 처리한다. 이전보다 더 빠르게 예외를 응답할 수 있다.
1 parent feb828f commit b795eb8

File tree

3 files changed

+49
-12
lines changed

3 files changed

+49
-12
lines changed

src/main/java/com/example/solidconnection/auth/service/AuthService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@
1717

1818
import static com.example.solidconnection.config.token.TokenType.ACCESS;
1919
import static com.example.solidconnection.config.token.TokenType.REFRESH;
20-
import static com.example.solidconnection.config.token.TokenValidator.SIGN_OUT_VALUE;
2120
import static com.example.solidconnection.custom.exception.ErrorCode.REFRESH_TOKEN_EXPIRED;
2221

2322
@RequiredArgsConstructor
2423
@Service
2524
public class AuthService {
2625

26+
public static final String SIGN_OUT_VALUE = "signOut";
27+
2728
private final RedisTemplate<String, String> redisTemplate;
2829
private final TokenProvider tokenProvider;
2930
private final SiteUserRepository siteUserRepository;
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.example.solidconnection.config.security;
2+
3+
import com.example.solidconnection.config.token.TokenProvider;
4+
import com.example.solidconnection.custom.exception.CustomException;
5+
import jakarta.servlet.FilterChain;
6+
import jakarta.servlet.ServletException;
7+
import jakarta.servlet.http.HttpServletRequest;
8+
import jakarta.servlet.http.HttpServletResponse;
9+
import lombok.NonNull;
10+
import lombok.RequiredArgsConstructor;
11+
import org.springframework.data.redis.core.RedisTemplate;
12+
import org.springframework.stereotype.Component;
13+
import org.springframework.web.filter.OncePerRequestFilter;
14+
15+
import java.io.IOException;
16+
17+
import static com.example.solidconnection.auth.service.AuthService.SIGN_OUT_VALUE;
18+
import static com.example.solidconnection.config.token.TokenType.REFRESH;
19+
import static com.example.solidconnection.custom.exception.ErrorCode.USER_ALREADY_SIGN_OUT;
20+
21+
@Component
22+
@RequiredArgsConstructor
23+
public class SignOutCheckFilter extends OncePerRequestFilter {
24+
25+
private final RedisTemplate<String, String> redisTemplate;
26+
private final TokenProvider tokenProvider;
27+
private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
28+
29+
@Override
30+
protected void doFilterInternal(@NonNull HttpServletRequest request,
31+
@NonNull HttpServletResponse response,
32+
@NonNull FilterChain filterChain) throws ServletException, IOException {
33+
String token = tokenProvider.parseTokenFromRequest(request);
34+
if (token == null || !isSignOut(token)) {
35+
filterChain.doFilter(request, response);
36+
return;
37+
}
38+
39+
jwtAuthenticationEntryPoint.customCommence(response, new CustomException(USER_ALREADY_SIGN_OUT));
40+
}
41+
42+
private boolean isSignOut(String accessToken) {
43+
String subject = tokenProvider.parseSubject(accessToken);
44+
String refreshToken = REFRESH.addPrefixToSubject(subject);
45+
return SIGN_OUT_VALUE.equals(redisTemplate.opsForValue().get(refreshToken));
46+
}
47+
}

src/main/java/com/example/solidconnection/config/token/TokenValidator.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,11 @@
1919
import static com.example.solidconnection.custom.exception.ErrorCode.EMPTY_TOKEN;
2020
import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_SERVICE_PUBLISHED_KAKAO_TOKEN;
2121
import static com.example.solidconnection.custom.exception.ErrorCode.REFRESH_TOKEN_EXPIRED;
22-
import static com.example.solidconnection.custom.exception.ErrorCode.USER_ALREADY_SIGN_OUT;
2322

2423
@Component
2524
@RequiredArgsConstructor
2625
public class TokenValidator {
2726

28-
public static final String SIGN_OUT_VALUE = "signOut";
29-
3027
private final RedisTemplate<String, String> redisTemplate;
3128

3229
@Value("${jwt.secret}")
@@ -35,7 +32,6 @@ public class TokenValidator {
3532
public void validateAccessToken(String token) {
3633
validateTokenNotEmpty(token);
3734
validateTokenNotExpired(token, ACCESS);
38-
validateNotSignOut(token);
3935
validateRefreshToken(token);
4036
}
4137

@@ -64,13 +60,6 @@ private void validateTokenNotExpired(String token, TokenType tokenType) {
6460
}
6561
}
6662

67-
private void validateNotSignOut(String token) {
68-
String email = getClaim(token).getSubject();
69-
if (SIGN_OUT_VALUE.equals(redisTemplate.opsForValue().get(REFRESH.addPrefixToSubject(email)))) {
70-
throw new CustomException(USER_ALREADY_SIGN_OUT);
71-
}
72-
}
73-
7463
private void validateRefreshToken(String token) {
7564
String email = getClaim(token).getSubject();
7665
if (redisTemplate.opsForValue().get(REFRESH.addPrefixToSubject(email)) == null) {

0 commit comments

Comments
 (0)