diff --git a/src/main/java/ceos/backend/domain/admin/AdminController.java b/src/main/java/ceos/backend/domain/admin/AdminController.java index a982cf6e..439152f6 100644 --- a/src/main/java/ceos/backend/domain/admin/AdminController.java +++ b/src/main/java/ceos/backend/domain/admin/AdminController.java @@ -7,6 +7,7 @@ import ceos.backend.global.config.user.AdminDetails; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -21,6 +22,8 @@ public class AdminController { private final AdminService adminService; + private static final String MOBILE = "mobile"; + private static final String WEB = "web"; @Operation(summary = "닉네임 확인") @PostMapping("/username") @@ -38,9 +41,10 @@ public void signUp(@RequestBody @Valid SignUpRequest signUpRequest) { @Operation(summary = "로그인") @PostMapping("/signin") - public TokenResponse signIn(@RequestBody @Valid SignInRequest signInRequest) { + public TokenResponse signIn(HttpServletRequest request, @RequestBody @Valid SignInRequest signInRequest) { log.info("로그인"); - return adminService.signIn(signInRequest); + String device = request.getHeader("User-Agent").contains("mobile") ? MOBILE : WEB; + return adminService.signIn(device, signInRequest); } @Operation(summary = "아이디 찾기") @@ -68,9 +72,10 @@ public void resetPwd( @Operation(summary = "로그아웃") @PostMapping("/logout") - public void logout(@AuthenticationPrincipal AdminDetails adminUser) { + public void logout(HttpServletRequest request, @AuthenticationPrincipal AdminDetails adminUser) { log.info("로그아웃"); - adminService.logout(adminUser); + String device = request.getHeader("User-Agent").contains("mobile") ? MOBILE : WEB; + adminService.logout(device, adminUser); } @Operation(summary = "토큰 재발급") diff --git a/src/main/java/ceos/backend/domain/admin/service/AdminService.java b/src/main/java/ceos/backend/domain/admin/service/AdminService.java index 08c2c54e..7179b5ae 100644 --- a/src/main/java/ceos/backend/domain/admin/service/AdminService.java +++ b/src/main/java/ceos/backend/domain/admin/service/AdminService.java @@ -51,16 +51,18 @@ public void signUp(SignUpRequest signUpRequest) { } @Transactional - public TokenResponse signIn(SignInRequest signInRequest) { + public TokenResponse signIn(String device, SignInRequest signInRequest) { final Admin admin = adminHelper.findForSignIn(signInRequest); final Authentication authentication = adminHelper.adminAuthorizationInput(admin); adminHelper.checkRole(admin); + String redisKey = admin.getId().toString() + ":" + device; + // 토큰 발급 final String accessToken = tokenProvider.createAccessToken(admin.getId(), authentication); - final String refreshToken = tokenProvider.createRefreshToken(admin.getId(), authentication); + final String refreshToken = tokenProvider.createRefreshToken(admin.getId(), authentication, redisKey); return adminMapper.toTokenResponse(accessToken, refreshToken); } @@ -97,11 +99,13 @@ public void resetPwd(ResetPwdRequest resetPwdRequest, AdminDetails adminUser) { } @Transactional - public void logout(AdminDetails adminUser) { + public void logout(String device, AdminDetails adminUser) { final Admin admin = adminUser.getAdmin(); + String redisKey = admin.getId().toString() + ":" + device; + // 레디스 삭제 - tokenProvider.deleteRefreshToken(admin.getId()); + tokenProvider.deleteRefreshToken(redisKey); } @Transactional diff --git a/src/main/java/ceos/backend/global/config/RedisConfig.java b/src/main/java/ceos/backend/global/config/RedisConfig.java index a1570ec5..a43ee2dc 100644 --- a/src/main/java/ceos/backend/global/config/RedisConfig.java +++ b/src/main/java/ceos/backend/global/config/RedisConfig.java @@ -25,10 +25,7 @@ public RedisConnectionFactory redisConnectionFactory() { @Bean public RedisTemplate redisTemplate() { - // redisTemplate를 받아와서 set, get, delete를 사용 RedisTemplate redisTemplate = new RedisTemplate<>(); - // setKeySerializer, setValueSerializer 설정 - // redis-cli을 통해 직접 데이터를 조회 시 알아볼 수 없는 형태로 출력되는 것을 방지 redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new StringRedisSerializer()); redisTemplate.setConnectionFactory(redisConnectionFactory()); diff --git a/src/main/java/ceos/backend/global/config/jwt/TokenProvider.java b/src/main/java/ceos/backend/global/config/jwt/TokenProvider.java index d9f7ca90..5d1268e3 100644 --- a/src/main/java/ceos/backend/global/config/jwt/TokenProvider.java +++ b/src/main/java/ceos/backend/global/config/jwt/TokenProvider.java @@ -82,7 +82,7 @@ public String createAccessToken(Long id, Authentication authentication) { .compact(); } - public String createRefreshToken(Long id, Authentication authentication) { + public String createRefreshToken(Long id, Authentication authentication, String redisKey) { String authorities = authentication.getAuthorities().stream() .map(GrantedAuthority::getAuthority) @@ -107,13 +107,13 @@ public String createRefreshToken(Long id, Authentication authentication) { redisTemplate .opsForValue() - .set(id.toString(), refreshToken, refreshExpirationTime, TimeUnit.SECONDS); + .set(redisKey, refreshToken, refreshExpirationTime, TimeUnit.SECONDS); return refreshToken; } - public void deleteRefreshToken(Long id) { - redisTemplate.delete(id.toString()); + public void deleteRefreshToken(String redisKey) { + redisTemplate.delete(redisKey); } public String getTokenUserId(String token) {