Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] 사용자 로그인 api & 토큰 재발급 api & JWT 인증인가 세팅 #59

Merged
merged 68 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from 47 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
8b37d37
[feat]: auth repository 구현
ParkJuhan94 Jan 3, 2024
1906cdc
[feat]: build.gradle 에 jwt 의존성 추가
ParkJuhan94 Jan 3, 2024
ca28c66
[feat]: user repository 구현
ParkJuhan94 Jan 3, 2024
eed29d2
[feat]: Auth 엔티티 구현
ParkJuhan94 Jan 3, 2024
2840f78
[feat]: user 엔티티 구현
ParkJuhan94 Jan 3, 2024
971fc68
[feat]: UserJoinRequestDto 와 userinfo 구현
ParkJuhan94 Jan 3, 2024
365f1f8
[feat]: auth 컨트롤러 구현
ParkJuhan94 Jan 3, 2024
684657c
[feat]: Auth errorcode, Auth exception 구현
ParkJuhan94 Jan 3, 2024
9af6a9a
[feat]: Auth dto 구현
ParkJuhan94 Jan 3, 2024
6d345aa
[feat]: Auth Service 와 테스트 구현
ParkJuhan94 Jan 3, 2024
a919e65
[feat]: User service 와 errorcode 구현
ParkJuhan94 Jan 3, 2024
3c11e81
[feat]: Token 타입 구현
ParkJuhan94 Jan 3, 2024
53a6ee7
[feat]: @JwtAuthorization 어노테이션 & argument resolver 구현
ParkJuhan94 Jan 3, 2024
7515251
[feat]: JwtProvider 구현
ParkJuhan94 Jan 3, 2024
7c49c81
[feat]: JwtInterceptor 구현 및 WebConfig 구현
ParkJuhan94 Jan 3, 2024
002fc23
Merge branch 'dev' into feat/#3/login-api-1
ParkJuhan94 Jan 3, 2024
31ae841
[refactor]: user 관련된 것 수정
ParkJuhan94 Jan 5, 2024
f3a87ed
[refactor]: 인증 필요없는 api 구현 + jwtProvider 구현
ParkJuhan94 Jan 5, 2024
e048411
[refactor]: 필요없는 것 삭제 + 사소한 것 추가
ParkJuhan94 Jan 5, 2024
df39bd2
[feat]: authService + authController 구현
ParkJuhan94 Jan 5, 2024
5a99852
[feat]: 컨트롤러 요청 받기위한 레코드 + 토큰 레코드에 헤더이름 추가
ParkJuhan94 Jan 5, 2024
a9ed352
[feat]: JwtAuthorizationArgumentResolver 구현
ParkJuhan94 Jan 5, 2024
3262d37
feat : Auditing 설정 추가 (#57)
EunChanNam Jan 4, 2024
b6b0f08
[feat]: 공연 예매 API 추가 (#56)
ssssujini99 Jan 4, 2024
5099c53
[feat]: @NoAuth 로 api 인증 필요여부 구현
ParkJuhan94 Jan 5, 2024
f4de857
[feat]: @NeedAuth 로 api 인증 필요여부 구현
ParkJuhan94 Jan 5, 2024
8178fe2
[feat]: userInfo, TokenType 삭제
ParkJuhan94 Jan 6, 2024
4c30c89
[feat]: api, scheduler 모듈의 test 의 yml 에 jwt 정보 추가
ParkJuhan94 Jan 6, 2024
834bce3
[feat]: Auth 에러코드 삭제 & AuthResponse 필드 변경
ParkJuhan94 Jan 6, 2024
2b4c6be
[feat]: user엔티티 생성자 추가
ParkJuhan94 Jan 6, 2024
934bd7c
[feat]: Argument Resolver를 통한 @NoAuth 구현
ParkJuhan94 Jan 6, 2024
b548328
[feat]: TokenForReIssue 네이밍 변경
ParkJuhan94 Jan 6, 2024
22a923f
[feat]: Api 들에다가 @NoAuth 추가
ParkJuhan94 Jan 6, 2024
831ab31
[feat]: AuthService 로직 변경 & AuthServiceTest 트러블슈팅
ParkJuhan94 Jan 6, 2024
c57fd03
[feat]: JwtProvider 로직 변경해서 구현
ParkJuhan94 Jan 6, 2024
bea0e88
[feat]: 인터셉터 로직 변경해서 구현
ParkJuhan94 Jan 6, 2024
07403af
[refactor]: WaitingBookingApiController 에 argument resolver 리팩토링 & Wa…
ParkJuhan94 Jan 6, 2024
32151d3
Merge remote-tracking branch 'origin/feat/#3/login-api-1' into feat/#…
ParkJuhan94 Jan 6, 2024
98fc9a0
[feat]: core 모듈 test의 yml 에 jwt 정보 추가
ParkJuhan94 Jan 6, 2024
f8ae263
Revert "feat : Auditing 설정 추가 (#57)"
ParkJuhan94 Jan 7, 2024
2158c92
Revert "[feat]: 공연 예매 API 추가 (#56)"
ParkJuhan94 Jan 7, 2024
f311f64
Revert "Revert "[feat]: 공연 예매 API 추가 (#56)""
ParkJuhan94 Jan 7, 2024
1d945cf
Revert "[feat]: 공연 예매 API 추가 (#56)"
ParkJuhan94 Jan 7, 2024
ee7192c
Merge branch 'dev' into feat/#3/login-api-1
ParkJuhan94 Jan 7, 2024
bdadcc2
[feat]: api 들에게 @NoAuth 추가
ParkJuhan94 Jan 7, 2024
0a7e2c9
[feat]: WaitingBookingApiControllerTest 되돌림
ParkJuhan94 Jan 7, 2024
5c8ec3e
[fix]: 테스트유저 생성자 변경
ParkJuhan94 Jan 7, 2024
9f1bdbf
[refactor]: jwt 헤더 yml -> 코드로 이동
ParkJuhan94 Jan 7, 2024
ca6ab3a
[refactor]: 토큰재발행 dto 네이밍 변경 & getAuthByRefreshToken 제어자 private 으로 변경
ParkJuhan94 Jan 7, 2024
49ec809
[refactor]: 시크릿키 생성 관련을 생성자로 ㅂ
ParkJuhan94 Jan 7, 2024
090d325
[refactor]: 로그인시에 토큰 생성하고, Auth를 생성하는 로직 변경, 그에 따른 테스트 변경
ParkJuhan94 Jan 7, 2024
f751298
[refactor]: JwtProvider 에서 AuthRepository 제거
ParkJuhan94 Jan 7, 2024
f32d9d8
[fix]: JwtProvider 에 검증할 예외 추가
ParkJuhan94 Jan 8, 2024
e3b54ae
[fix]: 인터셉터 로직 변경 - 예외를 jwtProvider 에서 처리하도록
ParkJuhan94 Jan 8, 2024
149abd9
[feat]: 테스트를 위한 JwtProvider 에 메서드와 생성자 추가 + JwtProviderTest 구현
ParkJuhan94 Jan 8, 2024
3415059
[feat]: ShowSeatsApiController 머지 적용
ParkJuhan94 Jan 9, 2024
612a766
[feat] : 예매된 좌석 조회 API 구현 (#63)
EunChanNam Jan 8, 2024
7b5bbb4
[refactor]: JwtInterceptorTest 정리
ParkJuhan94 Jan 9, 2024
da2a5f7
[feat]: ShowSeatsApiController 머지하면서 @NoAuth 추가
ParkJuhan94 Jan 9, 2024
09487e0
[feat]: 아규먼트리졸버 테스트 구현 & 인터셉터 테스트 로직 정리
ParkJuhan94 Jan 9, 2024
51ce8fa
Merge branch 'dev' into feat/#3/login-api-1
ParkJuhan94 Jan 9, 2024
a35ed44
[feat]: AuthApiControllerTest 구현
ParkJuhan94 Jan 9, 2024
c1812a8
Merge remote-tracking branch 'origin/feat/#3/login-api-1' into feat/#…
ParkJuhan94 Jan 9, 2024
155d940
[feat]: [api 모듈 auth 패키지]의 하위를 패키지 정리
ParkJuhan94 Jan 9, 2024
36bb5c4
[feat]: JwtProvider 테스트용 생성자 메서드 삭제에 따른 테스트코드도 함께 변경
ParkJuhan94 Jan 9, 2024
3f23088
[feat]: AuthJpaRepository 정리
ParkJuhan94 Jan 9, 2024
9a33959
[feat]: AuthApiControllerTest 정리와 AuthService 의 saveAuth 접근제어자 변경
ParkJuhan94 Jan 9, 2024
add77b1
[feat]: 인터셉터와 아규먼트리졸버 테스트 각각에서 @ExtendWith 추가와 setUp() 을 필드에 직접 할당으로 변경
ParkJuhan94 Jan 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions api/src/main/java/dev/hooon/auth/AuthApiController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package dev.hooon.auth;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import dev.hooon.auth.application.AuthService;
import dev.hooon.auth.dto.request.AuthRequest;

import dev.hooon.auth.dto.response.AuthResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
ParkJuhan94 marked this conversation as resolved.
Show resolved Hide resolved
@RequestMapping("/api/auth")
@RestController
@RequiredArgsConstructor
public class AuthApiController {

private final AuthService authService;

@NoAuth
@PostMapping("/login")
public ResponseEntity<AuthResponse> login(
@Valid @RequestBody AuthRequest authRequest
) {
AuthResponse authResponse = authService.login(authRequest);
return ResponseEntity.ok(authResponse);
}

@NoAuth
@PostMapping("/token")
public ResponseEntity<String> reIssueAccessToken(
@RequestBody TokenForReIssue tokenForReIssue
) {
String accessToken = authService.createAccessTokenByRefreshToken(tokenForReIssue.refreshToken());
return ResponseEntity.ok(accessToken);
}
}
15 changes: 15 additions & 0 deletions api/src/main/java/dev/hooon/auth/JwtAuthorization.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package dev.hooon.auth;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface JwtAuthorization {

// boolean required() default true;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package dev.hooon.auth;

import static dev.hooon.auth.exception.AuthErrorCode.*;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.MethodParameter;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import dev.hooon.auth.application.JwtProvider;
import dev.hooon.common.exception.NotFoundException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
ParkJuhan94 marked this conversation as resolved.
Show resolved Hide resolved
@Component
@RequiredArgsConstructor
public class JwtAuthorizationArgumentResolver implements HandlerMethodArgumentResolver {

private final JwtProvider jwtProvider;

@Value(value = "${jwt.header}")
private String jwtHeader;
ParkJuhan94 marked this conversation as resolved.
Show resolved Hide resolved

@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(JwtAuthorization.class);
}

@Override
public Object resolveArgument(
@NonNull MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory
) {
HttpServletRequest httpServletRequest = webRequest.getNativeRequest(HttpServletRequest.class);

if (httpServletRequest != null) {
String accessToken = httpServletRequest.getHeader(jwtHeader);
return jwtProvider.getClaim(accessToken);
}

throw new NotFoundException(NOT_FOUND_REQUEST);
}

}
56 changes: 56 additions & 0 deletions api/src/main/java/dev/hooon/auth/JwtInterceptor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package dev.hooon.auth;

import static dev.hooon.auth.exception.AuthErrorCode.*;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import dev.hooon.auth.application.JwtProvider;
import dev.hooon.auth.exception.AuthException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
@RequiredArgsConstructor
public class JwtInterceptor implements HandlerInterceptor {

private final JwtProvider jwtProvider;

@Value(value = "${jwt.header}")
private String jwtHeader;

private boolean isAnnotationPresent(Object handler) {
HandlerMethod handlerMethod = (HandlerMethod)handler;
return handlerMethod.getMethodAnnotation(NoAuth.class) != null;
}

@Override
public boolean preHandle(
@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull Object handler
) {
if (isAnnotationPresent(handler)) {
return true;
}

String accessToken = request.getHeader(jwtHeader);
if (accessToken == null) {
throw new AuthException(NOT_INCLUDE_ACCESS_TOKEN);
}

try {
jwtProvider.validateToken(accessToken);
} catch (AuthException e) {
return false;
}
ParkJuhan94 marked this conversation as resolved.
Show resolved Hide resolved

return true;
}
}
11 changes: 11 additions & 0 deletions api/src/main/java/dev/hooon/auth/NoAuth.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package dev.hooon.auth;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface NoAuth {
}
7 changes: 7 additions & 0 deletions api/src/main/java/dev/hooon/auth/TokenForReIssue.java
ParkJuhan94 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package dev.hooon.auth;


public record TokenForReIssue(
String refreshToken
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import dev.hooon.auth.NoAuth;
import dev.hooon.booking.application.BookingService;
import dev.hooon.booking.dto.response.BookingCancelResponse;
import lombok.RequiredArgsConstructor;
Expand All @@ -16,6 +17,7 @@ public class BookingCancelApiController {

private final BookingService bookingService;

@NoAuth
@PostMapping("/api/bookings/cancel/{booking_id}")
public ResponseEntity<BookingCancelResponse> cancelBooking(
@RequestParam(name = "userId") Long userId, // TODO
Expand Down
31 changes: 31 additions & 0 deletions api/src/main/java/dev/hooon/common/exception/config/WebConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package dev.hooon.common.exception.config;

import java.util.List;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import dev.hooon.auth.JwtAuthorizationArgumentResolver;
import dev.hooon.auth.JwtInterceptor;
import lombok.RequiredArgsConstructor;

@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {

private final JwtAuthorizationArgumentResolver jwtAuthorizationArgumentResolver;
private final JwtInterceptor jwtInterceptor;

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(jwtAuthorizationArgumentResolver);
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor)
.addPathPatterns("/api/**");
}
}
2 changes: 2 additions & 0 deletions api/src/main/java/dev/hooon/show/RankingApiController.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RestController;

import dev.hooon.auth.NoAuth;
import dev.hooon.show.application.facade.RankingCacheFacade;
import dev.hooon.show.dto.request.RankingRequest;
import dev.hooon.show.dto.response.RankingResponse;
Expand All @@ -17,6 +18,7 @@ public class RankingApiController {

private final RankingCacheFacade rankingCacheFacade;

@NoAuth
@GetMapping("/api/shows/ranking")
public ResponseEntity<RankingResponse> getShowRanking(@Valid @ModelAttribute RankingRequest request) {
RankingResponse rankingResponse = rankingCacheFacade.getShowRankingWithCache(request);
Expand Down
2 changes: 2 additions & 0 deletions api/src/main/java/dev/hooon/show/ShowApiController.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import dev.hooon.auth.NoAuth;
import dev.hooon.show.application.ShowService;
import dev.hooon.show.dto.response.AbleBookingDateRoundResponse;
import lombok.RequiredArgsConstructor;
Expand All @@ -15,6 +16,7 @@ public class ShowApiController {

private final ShowService showService;

@NoAuth
@GetMapping("/api/shows/{show_id}/available")
public ResponseEntity<AbleBookingDateRoundResponse> getAbleBookingDateRoundInfo(
@PathVariable("show_id") Long showId
Expand Down
2 changes: 2 additions & 0 deletions api/src/main/java/dev/hooon/show/ShowDetailApiController.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import dev.hooon.auth.NoAuth;
import dev.hooon.show.application.ShowService;
import dev.hooon.show.dto.response.ShowDetailsInfoResponse;
import lombok.RequiredArgsConstructor;
Expand All @@ -15,6 +16,7 @@ public class ShowDetailApiController {

private final ShowService showService;

@NoAuth
@GetMapping("/api/shows/{show_id}")
public ResponseEntity<ShowDetailsInfoResponse> getShowDetailInfo(
@PathVariable("show_id") Long showId
Expand Down
2 changes: 2 additions & 0 deletions api/src/main/java/dev/hooon/show/ShowSeatsApiController.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import dev.hooon.auth.NoAuth;
import dev.hooon.show.application.ShowSeatsService;
import dev.hooon.show.dto.response.seats.ShowSeatsResponse;
import lombok.RequiredArgsConstructor;
Expand All @@ -19,6 +20,7 @@ public class ShowSeatsApiController {

private final ShowSeatsService showSeatsService;

@NoAuth
@GetMapping("/api/shows/{showId}/seats")
public ResponseEntity<ShowSeatsResponse> getShowSeatsInfo(
@PathVariable("showId") Long showId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import dev.hooon.auth.NoAuth;
import dev.hooon.booking.application.fascade.TicketBookingFacade;
import dev.hooon.booking.dto.request.TicketBookingRequest;
import dev.hooon.booking.dto.response.TicketBookingResponse;
Expand All @@ -18,6 +19,7 @@ public class TicketBookingApiController {

private final TicketBookingFacade ticketBookingFacade;

@NoAuth
@PostMapping("/api/bookings")
public ResponseEntity<TicketBookingResponse> bookingTicket(
@RequestParam(name = "userId") Long userId, // TODO
Expand Down
2 changes: 2 additions & 0 deletions api/src/main/java/dev/hooon/user/UserApiController.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import dev.hooon.auth.NoAuth;
import dev.hooon.user.application.UserService;
import dev.hooon.user.dto.request.UserJoinRequest;
import dev.hooon.user.dto.response.UserJoinResponse;
Expand All @@ -17,6 +18,7 @@ public class UserApiController {

private final UserService userService;

@NoAuth
@PostMapping("/api/users")
public ResponseEntity<UserJoinResponse> join(
final @Valid @RequestBody UserJoinRequest userJoinRequest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import dev.hooon.auth.NoAuth;
import dev.hooon.waitingbooking.application.facade.WaitingBookingFacade;
import dev.hooon.waitingbooking.dto.request.WaitingRegisterRequest;
import dev.hooon.waitingbooking.dto.response.WaitingRegisterResponse;
Expand All @@ -18,6 +19,7 @@ public class WaitingBookingApiController {

private final WaitingBookingFacade waitingBookingFacade;

@NoAuth
@PostMapping("/api/waiting_bookings")
public ResponseEntity<WaitingRegisterResponse> registerWaitingBooking(
@RequestParam(name = "userId") Long userId, // TODO 추후에 인증정보 ArgumentResolver 가 구현되면 수정 예정
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,4 @@ void registerWaitingBookingTest() throws Exception {
jsonPath("$.waitingBookingId").value(allWaitingBookings.get(0).getId())
);
}
}
}
7 changes: 6 additions & 1 deletion api/src/test/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,9 @@ spring:

logging:
level:
org.hibernate.sql: info
org.hibernate.sql: info

jwt:
header: Authorization
secret: fdflsjhflkwejfblkjhvuixochvuhsofiuesafbidsfab223411
token-validity-in-seconds: 2400
4 changes: 4 additions & 0 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ dependencies {
testFixturesImplementation 'org.springframework:spring-tx:6.1.1'
// 패스워드 암호화
implementation group: 'org.mindrot', name: 'jbcrypt', version: '0.3m'
// JWT
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
// 레디스 LocalDateTime 역직렬화
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
implementation 'com.fasterxml.jackson.core:jackson-databind'
Expand Down
Loading
Loading