[api] AdminAuthController 이쪽 컨벤션 맞춰 변경

This commit is contained in:
2026-05-21 16:56:04 +09:00
parent 4c30133285
commit 05cf8281f2
14 changed files with 278 additions and 207 deletions
+2
View File
@@ -23,6 +23,8 @@
- DTO 안에 연관된 다른 DTO 변환이 꼭 필요할 때만 최소한의 보조 메서드를 둔다. - DTO 안에 연관된 다른 DTO 변환이 꼭 필요할 때만 최소한의 보조 메서드를 둔다.
- 외부 응답에 노출되면 안 되는 내부 필드는 응답에 사용될 수 있는 객체에서 `@JsonIgnore`로 숨긴다. - 외부 응답에 노출되면 안 되는 내부 필드는 응답에 사용될 수 있는 객체에서 `@JsonIgnore`로 숨긴다.
- 등록, 수정, 삭제, 상태 변경처럼 처리 여부만 반환하는 VO 의 boolean 필드는 `processed` 로 통일한다. 예: `private boolean processed;` - 등록, 수정, 삭제, 상태 변경처럼 처리 여부만 반환하는 VO 의 boolean 필드는 `processed` 로 통일한다. 예: `private boolean processed;`
- Controller 요청/응답 타입은 가능한 한 Form/Dto/Vo 로 명시한다. `Map<String, Object>` 는 응답 구조가 고정되지 않는 임시 디버깅, 외부 라이브러리 passthrough 같은 예외 상황에서만 제한적으로 사용한다.
- 응답 필드가 단순 boolean 몇 개뿐이어도 운영 API 에서는 VO 를 만든다. 예: 로그인 상태 확인 응답은 `Map<String, Object>` 보다 `AdminAuthLoginCheckedVo` 를 사용한다.
- 목록 조회 API 는 특별한 사유가 없으면 기본적으로 페이징을 적용하고, 목록 조회 Form/Dto 는 `PageRequest`, 목록 응답 Vo 는 `PageResponse` 를 상속한다. - 목록 조회 API 는 특별한 사유가 없으면 기본적으로 페이징을 적용하고, 목록 조회 Form/Dto 는 `PageRequest`, 목록 응답 Vo 는 `PageResponse` 를 상속한다.
## Swagger/OpenAPI 문서화 규칙 ## Swagger/OpenAPI 문서화 규칙
@@ -4,11 +4,10 @@ import com.alist.api.common.response.ApiResponse;
import com.alist.api.common.response.ApiResponseCode; import com.alist.api.common.response.ApiResponseCode;
import com.alist.api.common.utils.SecurityUtil; import com.alist.api.common.utils.SecurityUtil;
import com.alist.api.common.utils.SessionUtil; import com.alist.api.common.utils.SessionUtil;
import com.alist.api.modules.admin.auth.form.AdminApiKeyLoginForm; import com.alist.api.modules.admin.auth.form.AdminAuthApiKeyLoginForm;
import com.alist.api.modules.admin.auth.form.AdminLoginForm; import com.alist.api.modules.admin.auth.form.AdminAuthLoginForm;
import com.alist.api.modules.admin.auth.service.AdminAuthService; import com.alist.api.modules.admin.auth.service.AdminAuthService;
import com.alist.api.modules.admin.auth.vo.AdminApiKeyLoginVo; import com.alist.api.modules.admin.auth.vo.*;
import com.alist.api.modules.admin.auth.vo.AdminLoginVo;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
@@ -17,9 +16,6 @@ import jakarta.validation.Valid;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@Tag( @Tag(
name = "501. Admin 로그인" name = "501. Admin 로그인"
, description = "ADMIN 사이트 로그인입니다. 로그인시 토큰 발급이 함께됩니다." , description = "ADMIN 사이트 로그인입니다. 로그인시 토큰 발급이 함께됩니다."
@@ -39,34 +35,34 @@ public class AdminAuthController {
, description = "admin로그인 sso와 다르게 로그인시 토큰이 함께 발급됩니다." , description = "admin로그인 sso와 다르게 로그인시 토큰이 함께 발급됩니다."
) )
@PostMapping("/login") @PostMapping("/login")
public ResponseEntity<ApiResponse<AdminLoginVo>> adminLogin( public ResponseEntity<ApiResponse<AdminAuthLoginVo>> adminAuthLogin(
@Valid @RequestBody AdminLoginForm adminLoginForm @Valid @RequestBody AdminAuthLoginForm adminAuthLoginForm
, HttpServletResponse response , HttpServletResponse response
) { ) {
AdminLoginVo result = adminAuthService.adminLogin(adminLoginForm.toAdminLoginDto(), response); AdminAuthLoginVo adminAuthLoginVo = adminAuthService.selectAdminAuthLogin(adminAuthLoginForm.toDto(), response);
if (result.getResultCode() == 2003) { if (adminAuthLoginVo.getResultCode() == 2003) {
return ApiResponse.entity(result, ApiResponseCode.CODE_2003); return ApiResponse.entity(adminAuthLoginVo, ApiResponseCode.CODE_2003);
} }
return ApiResponse.entity(result, ApiResponseCode.CODE_2001, "관리자 로그인"); return ApiResponse.entity(adminAuthLoginVo, ApiResponseCode.CODE_2001, "관리자 로그인");
} }
@Operation( @Operation(
summary = "admin API Key 로그인", summary = "admin API Key 로그인"
description = "Admin API Key로 인증하고 JSON으로 토큰을 반환합니다. Swagger 테스트용입니다." , description = "Admin API Key로 인증하고 JSON으로 토큰을 반환합니다. Swagger 테스트용입니다."
) )
@PostMapping("/apiKeyLogin") @PostMapping("/apiKeyLogin")
public ResponseEntity<ApiResponse<AdminApiKeyLoginVo>> adminApiKeyLogin( public ResponseEntity<ApiResponse<AdminAuthApiKeyLoginVo>> adminAuthApiKeyLogin(
@Valid @RequestBody AdminApiKeyLoginForm adminApiKeyLoginForm @Valid @RequestBody AdminAuthApiKeyLoginForm adminAuthApiKeyLoginForm
) { ) {
AdminApiKeyLoginVo result = adminAuthService.adminApiKeyLogin(adminApiKeyLoginForm.toAdminApiKeyLoginDto()); AdminAuthApiKeyLoginVo adminAuthApiKeyLoginVo = adminAuthService.selectAdminAuthApiKeyLogin(adminAuthApiKeyLoginForm.toDto());
if (result.getResultCode() == 2003) { if (adminAuthApiKeyLoginVo.getResultCode() == 2003) {
return ApiResponse.entity(result, ApiResponseCode.CODE_2003); return ApiResponse.entity(adminAuthApiKeyLoginVo, ApiResponseCode.CODE_2003);
} }
return ApiResponse.entity(result, ApiResponseCode.CODE_2001, "관리자 엑세스 토큰"); return ApiResponse.entity(adminAuthApiKeyLoginVo, ApiResponseCode.CODE_2001, "관리자 엑세스 토큰");
} }
@Operation( @Operation(
@@ -74,57 +70,60 @@ public class AdminAuthController {
, description = "엑세스 토큰 만료시 리프레시 토큰 발급 용도 api 입니다." , description = "엑세스 토큰 만료시 리프레시 토큰 발급 용도 api 입니다."
) )
@PostMapping("/refresh") @PostMapping("/refresh")
public ResponseEntity<ApiResponse<Map<String, Object>>> refresh( public ResponseEntity<ApiResponse<AdminAuthRefreshVo>> adminAuthRefresh(
@CookieValue(name = "adminRefreshToken", required = false) String refreshToken @CookieValue(name = "adminRefreshToken", required = false) String refreshToken
, HttpServletResponse response , HttpServletResponse response
) { ) {
AdminLoginVo result = adminAuthService.adminRefresh(refreshToken, response); AdminAuthLoginVo adminAuthLoginVo = adminAuthService.selectAdminAuthRefresh(refreshToken, response);
if (result == null) { AdminAuthRefreshVo adminAuthRefreshVo = new AdminAuthRefreshVo();
return ApiResponse.entity(Map.of("refreshed", false), ApiResponseCode.CODE_401); adminAuthRefreshVo.setRefreshed(adminAuthLoginVo != null);
if (adminAuthLoginVo == null) {
return ApiResponse.entity(adminAuthRefreshVo, ApiResponseCode.CODE_401);
} }
return ApiResponse.entity(Map.of("refreshed", true), ApiResponseCode.CODE_200); return ApiResponse.entity(adminAuthRefreshVo, ApiResponseCode.CODE_200);
} }
@Operation( @Operation(
summary = "admin 로그인 상태 확인", summary = "admin 로그인 상태 확인"
description = "admin 쿠키 기준으로 현재 공통 로그인 상태가 유효한지 확인하고, access/refresh 토큰 존재 여부도 함께 반환합니다." , description = "admin 쿠키 기준으로 현재 공통 로그인 상태가 유효한지 확인하고, access/refresh 토큰 존재 여부도 함께 반환합니다."
) )
@GetMapping("/loginChecked") @GetMapping("/loginChecked")
public ResponseEntity<ApiResponse<Map<String, Object>>> loginChecked( public ResponseEntity<ApiResponse<AdminAuthLoginCheckedVo>> adminAuthLoginChecked(
HttpServletRequest request HttpServletRequest request
) { ) {
Map<String, Object> result = new HashMap<>(); AdminAuthLoginCheckedVo adminAuthLoginCheckedVo = new AdminAuthLoginCheckedVo();
String accessToken = SessionUtil.resolveSsoCookieValue(request, "adminAccessToken"); String accessToken = SessionUtil.resolveSsoCookieValue(request, "adminAccessToken");
String refreshToken = SessionUtil.resolveSsoCookieValue(request, "adminRefreshToken"); String refreshToken = SessionUtil.resolveSsoCookieValue(request, "adminRefreshToken");
result.put("isAdminAccessToken", accessToken != null && !accessToken.trim().isEmpty()); adminAuthLoginCheckedVo.setAdminAccessToken(accessToken != null && !accessToken.trim().isEmpty());
result.put("isAdminRefreshToken", refreshToken != null && !refreshToken.trim().isEmpty()); adminAuthLoginCheckedVo.setAdminRefreshToken(refreshToken != null && !refreshToken.trim().isEmpty());
Integer userTokenIdx = SecurityUtil.getLoginUserTokenIdx(); Integer userTokenIdx = SecurityUtil.getLoginUserTokenIdx();
if (userTokenIdx == null) { if (userTokenIdx == null) {
result.put("loggedIn", false); adminAuthLoginCheckedVo.setLoggedIn(false);
return ApiResponse.entity(result, ApiResponseCode.CODE_200); return ApiResponse.entity(adminAuthLoginCheckedVo, ApiResponseCode.CODE_200);
} }
AdminLoginVo admin = adminAuthService.selectAdminTokenByUserTokenIdx(userTokenIdx); AdminAuthLoginVo adminAuthLoginVo = adminAuthService.selectAdminAuthLoginChecked(userTokenIdx);
if (admin == null) { if (adminAuthLoginVo == null) {
result.put("loggedIn", false); adminAuthLoginCheckedVo.setLoggedIn(false);
return ApiResponse.entity(result, ApiResponseCode.CODE_200); return ApiResponse.entity(adminAuthLoginCheckedVo, ApiResponseCode.CODE_200);
} }
result.put("loggedIn", true); adminAuthLoginCheckedVo.setLoggedIn(true);
result.put("userId", admin.getId()); adminAuthLoginCheckedVo.setUserId(adminAuthLoginVo.getId());
result.put("userIdx", admin.getUserIdx()); adminAuthLoginCheckedVo.setUserIdx(adminAuthLoginVo.getUserIdx());
result.put("userTokenIdx", userTokenIdx); adminAuthLoginCheckedVo.setUserTokenIdx(userTokenIdx);
result.put("userRole", admin.getUserRole()); adminAuthLoginCheckedVo.setUserRole(adminAuthLoginVo.getUserRole());
result.put("userType", admin.getUserType()); adminAuthLoginCheckedVo.setUserType(adminAuthLoginVo.getUserType());
return ApiResponse.entity(result, ApiResponseCode.CODE_200); return ApiResponse.entity(adminAuthLoginCheckedVo, ApiResponseCode.CODE_200);
} }
@Operation( @Operation(
@@ -132,12 +131,15 @@ public class AdminAuthController {
, description = "admin 로그아웃" , description = "admin 로그아웃"
) )
@PostMapping("/logout") @PostMapping("/logout")
public ResponseEntity<ApiResponse<Map<String, Object>>> logout( public ResponseEntity<ApiResponse<AdminAuthLogoutVo>> adminAuthLogout(
@CookieValue(name = "adminRefreshToken", required = false) String refreshToken @CookieValue(name = "adminRefreshToken", required = false) String refreshToken
, HttpServletResponse response , HttpServletResponse response
) { ) {
adminAuthService.adminLogout(refreshToken, response); adminAuthService.updateAdminAuthLogout(refreshToken, response);
return ApiResponse.entity(Map.of("loggedOut", true), ApiResponseCode.CODE_200); AdminAuthLogoutVo adminAuthLogoutVo = new AdminAuthLogoutVo();
adminAuthLogoutVo.setLoggedOut(true);
return ApiResponse.entity(adminAuthLogoutVo, ApiResponseCode.CODE_200);
} }
} }
@@ -7,7 +7,7 @@ import java.time.Instant;
@Getter @Getter
@Setter @Setter
public class AdminApiKeyLoginDto { public class AdminAuthApiKeyLoginDto {
private String userApiKey; private String userApiKey;
private Integer userIdx; private Integer userIdx;
private Integer userTokenIdx; private Integer userTokenIdx;
@@ -7,7 +7,7 @@ import java.time.Instant;
@Setter @Setter
@Getter @Getter
public class AdminLoginDto { public class AdminAuthLoginDto {
private String id; private String id;
private String password; private String password;
@@ -1,6 +1,6 @@
package com.alist.api.modules.admin.auth.form; package com.alist.api.modules.admin.auth.form;
import com.alist.api.modules.admin.auth.dto.AdminApiKeyLoginDto; import com.alist.api.modules.admin.auth.dto.AdminAuthApiKeyLoginDto;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import lombok.Getter; import lombok.Getter;
@@ -9,7 +9,7 @@ import lombok.Setter;
@Schema(description = "Admin API Key 로그인 요청 폼") @Schema(description = "Admin API Key 로그인 요청 폼")
@Getter @Getter
@Setter @Setter
public class AdminApiKeyLoginForm { public class AdminAuthApiKeyLoginForm {
@Schema( @Schema(
description = "Admin API Key", description = "Admin API Key",
example = "ypdz9hl7WAp2D03HC5h9koEC49R6LAkLSuoSdgEwVQA", example = "ypdz9hl7WAp2D03HC5h9koEC49R6LAkLSuoSdgEwVQA",
@@ -18,9 +18,9 @@ public class AdminApiKeyLoginForm {
@NotBlank(message = "apiKey를 입력해주세요.") @NotBlank(message = "apiKey를 입력해주세요.")
private String userApiKey; private String userApiKey;
public AdminApiKeyLoginDto toAdminApiKeyLoginDto() { public AdminAuthApiKeyLoginDto toDto() {
AdminApiKeyLoginDto adminApiKeyLoginDto = new AdminApiKeyLoginDto(); AdminAuthApiKeyLoginDto adminAuthApiKeyLoginDto = new AdminAuthApiKeyLoginDto();
adminApiKeyLoginDto.setUserApiKey(userApiKey.trim()); adminAuthApiKeyLoginDto.setUserApiKey(userApiKey.trim());
return adminApiKeyLoginDto; return adminAuthApiKeyLoginDto;
} }
} }
@@ -1,6 +1,6 @@
package com.alist.api.modules.admin.auth.form; package com.alist.api.modules.admin.auth.form;
import com.alist.api.modules.admin.auth.dto.AdminLoginDto; import com.alist.api.modules.admin.auth.dto.AdminAuthLoginDto;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import lombok.Getter; import lombok.Getter;
@@ -9,7 +9,7 @@ import lombok.Setter;
@Schema(description = "Admin 로그인 요청 폼") @Schema(description = "Admin 로그인 요청 폼")
@Getter @Getter
@Setter @Setter
public class AdminLoginForm { public class AdminAuthLoginForm {
@Schema( @Schema(
description = "관리자 아이디", description = "관리자 아이디",
example = "admin", example = "admin",
@@ -26,11 +26,11 @@ public class AdminLoginForm {
@NotBlank(message = "비밀번호는 필수입니다.") @NotBlank(message = "비밀번호는 필수입니다.")
private String password; private String password;
public AdminLoginDto toAdminLoginDto() { public AdminAuthLoginDto toDto() {
AdminLoginDto adminLoginDto = new AdminLoginDto(); AdminAuthLoginDto adminAuthLoginDto = new AdminAuthLoginDto();
adminLoginDto.setId(id.trim()); adminAuthLoginDto.setId(id.trim());
adminLoginDto.setPassword(password); adminAuthLoginDto.setPassword(password);
return adminLoginDto; return adminAuthLoginDto;
} }
} }
@@ -1,24 +1,24 @@
package com.alist.api.modules.admin.auth.mapper; package com.alist.api.modules.admin.auth.mapper;
import com.alist.api.modules.admin.auth.dto.AdminApiKeyLoginDto; import com.alist.api.modules.admin.auth.dto.AdminAuthApiKeyLoginDto;
import com.alist.api.modules.admin.auth.dto.AdminLoginDto; import com.alist.api.modules.admin.auth.dto.AdminAuthLoginDto;
import com.alist.api.modules.admin.auth.vo.AdminApiKeyLoginVo; import com.alist.api.modules.admin.auth.vo.AdminAuthApiKeyLoginVo;
import com.alist.api.modules.admin.auth.vo.AdminLoginVo; import com.alist.api.modules.admin.auth.vo.AdminAuthLoginVo;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
@Mapper @Mapper
public interface AdminAuthMapper { public interface AdminAuthMapper {
AdminLoginVo selectAdminLoginById(String id); AdminAuthLoginVo selectAdminAuthLogin(String id);
void updateAdminRefreshToken(AdminLoginDto adminLoginDto); void updateAdminRefreshToken(AdminAuthLoginDto adminAuthLoginDto);
void updateAdminLastLoginAt(Integer userIdx); void updateAdminLastLoginAt(Integer userIdx);
AdminLoginVo selectAdminTokenByUserTokenIdx(Integer userTokenIdx); AdminAuthLoginVo selectAdminTokenByUserTokenIdx(Integer userTokenIdx);
void clearAdminRefreshToken(Integer userTokenIdx); void updateClearAdminRefreshToken(Integer userTokenIdx);
AdminApiKeyLoginVo selectAdminApiKeyLogin(AdminApiKeyLoginDto adminApiKeyLoginDto); AdminAuthApiKeyLoginVo selectAdminAuthApiKeyLogin(AdminAuthApiKeyLoginDto adminAuthApiKeyLoginDto);
void updateAdminApiKeyLoginRefreshToken(AdminApiKeyLoginDto adminApiKeyLoginDto); void updateAdminApiKeyLoginRefreshToken(AdminAuthApiKeyLoginDto adminAuthApiKeyLoginDto);
} }
@@ -2,11 +2,11 @@ package com.alist.api.modules.admin.auth.service;
import com.alist.api.common.utils.SessionUtil; import com.alist.api.common.utils.SessionUtil;
import com.alist.api.config.jwt.JwtTokenProvider; import com.alist.api.config.jwt.JwtTokenProvider;
import com.alist.api.modules.admin.auth.dto.AdminApiKeyLoginDto; import com.alist.api.modules.admin.auth.dto.AdminAuthApiKeyLoginDto;
import com.alist.api.modules.admin.auth.dto.AdminLoginDto; import com.alist.api.modules.admin.auth.dto.AdminAuthLoginDto;
import com.alist.api.modules.admin.auth.mapper.AdminAuthMapper; import com.alist.api.modules.admin.auth.mapper.AdminAuthMapper;
import com.alist.api.modules.admin.auth.vo.AdminApiKeyLoginVo; import com.alist.api.modules.admin.auth.vo.AdminAuthApiKeyLoginVo;
import com.alist.api.modules.admin.auth.vo.AdminLoginVo; import com.alist.api.modules.admin.auth.vo.AdminAuthLoginVo;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
@@ -43,42 +43,72 @@ public class AdminAuthService {
} }
@Transactional @Transactional
public AdminLoginVo adminLogin(AdminLoginDto adminLoginDto, HttpServletResponse response) { public AdminAuthLoginVo selectAdminAuthLogin(AdminAuthLoginDto adminAuthLoginDto, HttpServletResponse response) {
AdminLoginVo result = new AdminLoginVo(); AdminAuthLoginVo adminAuthLoginVo = adminAuthMapper.selectAdminAuthLogin(adminAuthLoginDto.getId());
AdminLoginVo adminLoginVo = adminAuthMapper.selectAdminLoginById(adminLoginDto.getId());
if (adminLoginVo == null) { if (adminAuthLoginVo == null) {
result.setResultCode(2003); AdminAuthLoginVo adminAuthLoginVo1 = new AdminAuthLoginVo();
result.setLogin(false); adminAuthLoginVo1.setResultCode(2003);
return result; adminAuthLoginVo1.setLogin(false);
return adminAuthLoginVo1;
} }
if (!passwordEncoder.matches(adminLoginDto.getPassword(), adminLoginVo.getPassword())) { if (!passwordEncoder.matches(adminAuthLoginDto.getPassword(), adminAuthLoginVo.getPassword())) {
result.setResultCode(2003); AdminAuthLoginVo adminAuthLoginVo1 = new AdminAuthLoginVo();
result.setLogin(false); adminAuthLoginVo1.setResultCode(2003);
return result; adminAuthLoginVo1.setLogin(false);
return adminAuthLoginVo1;
} }
String accessToken = jwtTokenProvider.createAdminAccessToken(adminLoginVo.getUserTokenIdx()); String accessToken = jwtTokenProvider.createAdminAccessToken(adminAuthLoginVo.getUserTokenIdx());
String refreshToken = jwtTokenProvider.createAdminRefreshToken(adminLoginVo.getUserTokenIdx()); String refreshToken = jwtTokenProvider.createAdminRefreshToken(adminAuthLoginVo.getUserTokenIdx());
adminLoginDto.setUserIdx(adminLoginVo.getUserIdx()); adminAuthLoginDto.setUserIdx(adminAuthLoginVo.getUserIdx());
adminLoginDto.setUserTokenIdx(adminLoginVo.getUserTokenIdx()); adminAuthLoginDto.setUserTokenIdx(adminAuthLoginVo.getUserTokenIdx());
adminLoginDto.setRefreshToken(refreshToken); adminAuthLoginDto.setRefreshToken(refreshToken);
adminLoginDto.setExpiresAt(Instant.now().plusSeconds(refreshTokenValiditySeconds)); adminAuthLoginDto.setExpiresAt(Instant.now().plusSeconds(refreshTokenValiditySeconds));
adminAuthMapper.updateAdminRefreshToken(adminLoginDto); adminAuthMapper.updateAdminRefreshToken(adminAuthLoginDto);
adminAuthMapper.updateAdminLastLoginAt(adminLoginDto.getUserIdx()); adminAuthMapper.updateAdminLastLoginAt(adminAuthLoginDto.getUserIdx());
SessionUtil.addTokenCookie(response,"adminAccessToken", accessToken, cookieDomain, cookieSecure, cookieSameSite, accessTokenValiditySeconds); SessionUtil.addTokenCookie(response, "adminAccessToken", accessToken, cookieDomain, cookieSecure, cookieSameSite, accessTokenValiditySeconds);
SessionUtil.addTokenCookie(response,"adminRefreshToken", refreshToken, cookieDomain, cookieSecure, cookieSameSite, refreshTokenValiditySeconds); SessionUtil.addTokenCookie(response, "adminRefreshToken", refreshToken, cookieDomain, cookieSecure, cookieSameSite, refreshTokenValiditySeconds);
adminLoginVo.setResultCode(2001); adminAuthLoginVo.setResultCode(2001);
adminLoginVo.setLogin(true); adminAuthLoginVo.setLogin(true);
return adminLoginVo; return adminAuthLoginVo;
} }
public AdminLoginVo adminRefresh(String refreshToken, HttpServletResponse response) { @Transactional
public AdminAuthApiKeyLoginVo selectAdminAuthApiKeyLogin(AdminAuthApiKeyLoginDto adminAuthApiKeyLoginDto) {
AdminAuthApiKeyLoginVo adminAuthApiKeyLoginVo = adminAuthMapper.selectAdminAuthApiKeyLogin(adminAuthApiKeyLoginDto);
if (adminAuthApiKeyLoginVo == null) {
AdminAuthApiKeyLoginVo adminAuthApiKeyLoginVo1 = new AdminAuthApiKeyLoginVo();
adminAuthApiKeyLoginVo1.setResultCode(2003);
adminAuthApiKeyLoginVo1.setLogin(false);
return adminAuthApiKeyLoginVo1;
}
String accessToken = jwtTokenProvider.createAdminAccessToken(adminAuthApiKeyLoginVo.getUserTokenIdx());
String refreshToken = jwtTokenProvider.createAdminRefreshToken(adminAuthApiKeyLoginVo.getUserTokenIdx());
adminAuthApiKeyLoginDto.setUserTokenIdx(adminAuthApiKeyLoginVo.getUserTokenIdx());
adminAuthApiKeyLoginDto.setRefreshToken(refreshToken);
adminAuthApiKeyLoginDto.setExpiresAt(Instant.now().plusSeconds(refreshTokenValiditySeconds));
adminAuthMapper.updateAdminApiKeyLoginRefreshToken(adminAuthApiKeyLoginDto);
adminAuthMapper.updateAdminLastLoginAt(adminAuthApiKeyLoginVo.getUserIdx());
adminAuthApiKeyLoginVo.setAccessToken(accessToken);
adminAuthApiKeyLoginVo.setRefreshToken(refreshToken);
adminAuthApiKeyLoginVo.setResultCode(2001);
adminAuthApiKeyLoginVo.setLogin(true);
return adminAuthApiKeyLoginVo;
}
public AdminAuthLoginVo selectAdminAuthRefresh(String refreshToken, HttpServletResponse response) {
if (refreshToken == null || !jwtTokenProvider.validateToken(refreshToken)) { if (refreshToken == null || !jwtTokenProvider.validateToken(refreshToken)) {
return null; return null;
} }
@@ -99,41 +129,41 @@ public class AdminAuthService {
return null; return null;
} }
AdminLoginVo adminToken = adminAuthMapper.selectAdminTokenByUserTokenIdx(userTokenIdx); AdminAuthLoginVo adminAuthLoginVo = adminAuthMapper.selectAdminTokenByUserTokenIdx(userTokenIdx);
if (adminToken == null || adminToken.getRefreshToken() == null) { if (adminAuthLoginVo == null || adminAuthLoginVo.getRefreshToken() == null) {
return null; return null;
} }
if (!refreshToken.equals(adminToken.getRefreshToken())) { if (!refreshToken.equals(adminAuthLoginVo.getRefreshToken())) {
return null; return null;
} }
String newAccessToken = jwtTokenProvider.createAdminAccessToken(userTokenIdx); String newAccessToken = jwtTokenProvider.createAdminAccessToken(userTokenIdx);
String newRefreshToken = jwtTokenProvider.createAdminRefreshToken(userTokenIdx); String newRefreshToken = jwtTokenProvider.createAdminRefreshToken(userTokenIdx);
AdminLoginDto adminLoginDto = new AdminLoginDto(); AdminAuthLoginDto adminAuthLoginDto = new AdminAuthLoginDto();
adminLoginDto.setUserTokenIdx(userTokenIdx); adminAuthLoginDto.setUserTokenIdx(userTokenIdx);
adminLoginDto.setRefreshToken(newRefreshToken); adminAuthLoginDto.setRefreshToken(newRefreshToken);
adminLoginDto.setExpiresAt(Instant.now().plusSeconds(refreshTokenValiditySeconds)); adminAuthLoginDto.setExpiresAt(Instant.now().plusSeconds(refreshTokenValiditySeconds));
adminAuthMapper.updateAdminRefreshToken(adminLoginDto); adminAuthMapper.updateAdminRefreshToken(adminAuthLoginDto);
SessionUtil.addTokenCookie(response, "adminAccessToken", newAccessToken, cookieDomain, cookieSecure, cookieSameSite, accessTokenValiditySeconds); SessionUtil.addTokenCookie(response, "adminAccessToken", newAccessToken, cookieDomain, cookieSecure, cookieSameSite, accessTokenValiditySeconds);
SessionUtil.addTokenCookie(response, "adminRefreshToken", newRefreshToken, cookieDomain, cookieSecure, cookieSameSite, refreshTokenValiditySeconds); SessionUtil.addTokenCookie(response, "adminRefreshToken", newRefreshToken, cookieDomain, cookieSecure, cookieSameSite, refreshTokenValiditySeconds);
adminToken.setResultCode(2001); adminAuthLoginVo.setResultCode(2001);
return adminToken; return adminAuthLoginVo;
} }
public void adminLogout(String refreshToken, HttpServletResponse response) { public void updateAdminAuthLogout(String refreshToken, HttpServletResponse response) {
clearAdminRefreshToken(refreshToken); updateClearAdminRefreshToken(refreshToken);
SessionUtil.expireCookie(response, "adminAccessToken", cookieDomain, cookieSecure, cookieSameSite); SessionUtil.expireCookie(response, "adminAccessToken", cookieDomain, cookieSecure, cookieSameSite);
SessionUtil.expireCookie(response, "adminRefreshToken", cookieDomain, cookieSecure, cookieSameSite); SessionUtil.expireCookie(response, "adminRefreshToken", cookieDomain, cookieSecure, cookieSameSite);
} }
private void clearAdminRefreshToken(String refreshToken) { private void updateClearAdminRefreshToken(String refreshToken) {
if (refreshToken == null || !jwtTokenProvider.validateToken(refreshToken)) { if (refreshToken == null || !jwtTokenProvider.validateToken(refreshToken)) {
return; return;
} }
@@ -148,45 +178,16 @@ public class AdminAuthService {
try { try {
Integer userTokenIdx = Integer.parseInt(jwtTokenProvider.getUserTokenIdx(refreshToken)); Integer userTokenIdx = Integer.parseInt(jwtTokenProvider.getUserTokenIdx(refreshToken));
adminAuthMapper.clearAdminRefreshToken(userTokenIdx); adminAuthMapper.updateClearAdminRefreshToken(userTokenIdx);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
} }
} }
public AdminLoginVo selectAdminTokenByUserTokenIdx(Integer userTokenIdx) { public AdminAuthLoginVo selectAdminAuthLoginChecked(Integer userTokenIdx) {
if (userTokenIdx == null) { if (userTokenIdx == null) {
return null; return null;
} }
return adminAuthMapper.selectAdminTokenByUserTokenIdx(userTokenIdx); return adminAuthMapper.selectAdminTokenByUserTokenIdx(userTokenIdx);
} }
@Transactional
public AdminApiKeyLoginVo adminApiKeyLogin(AdminApiKeyLoginDto adminApiKeyLoginDto) {
AdminApiKeyLoginVo result = adminAuthMapper.selectAdminApiKeyLogin(adminApiKeyLoginDto);
if (result == null) {
AdminApiKeyLoginVo empty = new AdminApiKeyLoginVo();
empty.setResultCode(2003);
empty.setLogin(false);
return empty;
}
String accessToken = jwtTokenProvider.createAdminAccessToken(result.getUserTokenIdx());
String refreshToken = jwtTokenProvider.createAdminRefreshToken(result.getUserTokenIdx());
adminApiKeyLoginDto.setUserTokenIdx(result.getUserTokenIdx());
adminApiKeyLoginDto.setRefreshToken(refreshToken);
adminApiKeyLoginDto.setExpiresAt(Instant.now().plusSeconds(refreshTokenValiditySeconds));
adminAuthMapper.updateAdminApiKeyLoginRefreshToken(adminApiKeyLoginDto);
adminAuthMapper.updateAdminLastLoginAt(result.getUserIdx());
result.setAccessToken(accessToken);
result.setRefreshToken(refreshToken);
result.setResultCode(2001);
result.setLogin(true);
return result;
}
} }
@@ -8,7 +8,7 @@ import lombok.Setter;
@Schema(description = "Admin API Key 로그인 응답") @Schema(description = "Admin API Key 로그인 응답")
@Getter @Getter
@Setter @Setter
public class AdminApiKeyLoginVo { public class AdminAuthApiKeyLoginVo {
@Schema(description = "로그인 성공 여부", example = "true") @Schema(description = "로그인 성공 여부", example = "true")
private boolean login; private boolean login;
@@ -0,0 +1,34 @@
package com.alist.api.modules.admin.auth.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
@Schema(description = "Admin 로그인 상태 확인 응답")
@Getter
@Setter
public class AdminAuthLoginCheckedVo {
@Schema(description = "Admin Access Token 쿠키 존재 여부", example = "true")
private boolean adminAccessToken;
@Schema(description = "Admin Refresh Token 쿠키 존재 여부", example = "true")
private boolean adminRefreshToken;
@Schema(description = "로그인 상태 여부", example = "true")
private boolean loggedIn;
@Schema(description = "관리자 아이디", example = "admin")
private String userId;
@Schema(description = "회원 PK", example = "14")
private Integer userIdx;
@Schema(description = "회원 토큰 PK", example = "14")
private Integer userTokenIdx;
@Schema(description = "관리자 권한 코드", example = "A")
private String userRole;
@Schema(description = "회원 유형 코드. A: 관리자", example = "A")
private String userType;
}
@@ -8,9 +8,9 @@ import lombok.Setter;
@Schema(description = "Admin 로그인 응답") @Schema(description = "Admin 로그인 응답")
@Setter @Setter
@Getter @Getter
public class AdminLoginVo { public class AdminAuthLoginVo {
@Schema(description = "로그인 성공 여부", example = "true") @Schema(description = "로그인 성공 여부", example = "true")
private boolean isLogin; private boolean login;
@Schema(description = "회원 PK", example = "14") @Schema(description = "회원 PK", example = "14")
private Integer userIdx; private Integer userIdx;
@@ -0,0 +1,13 @@
package com.alist.api.modules.admin.auth.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
@Schema(description = "Admin 로그아웃 응답")
@Getter
@Setter
public class AdminAuthLogoutVo {
@Schema(description = "로그아웃 처리 여부", example = "true")
private boolean loggedOut;
}
@@ -0,0 +1,13 @@
package com.alist.api.modules.admin.auth.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
@Schema(description = "Admin 리프레시 토큰 발급 응답")
@Getter
@Setter
public class AdminAuthRefreshVo {
@Schema(description = "리프레시 처리 여부", example = "true")
private boolean refreshed;
}
@@ -2,42 +2,8 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.alist.api.modules.admin.auth.mapper.AdminAuthMapper"> <mapper namespace="com.alist.api.modules.admin.auth.mapper.AdminAuthMapper">
<update id="updateAdminRefreshToken"> <select id="selectAdminAuthLogin" resultType="com.alist.api.modules.admin.auth.vo.AdminAuthLoginVo">
/*AdminLoginMapper.updateAdminRefreshToken*/ /*AdminAuthMapper.selectAdminAuthLogin*/
UPDATE ALISTLMS.test_user_token
SET refresh_token = #{refreshToken}
, expires_at = #{expiresAt}
, updated_at = now()
WHERE user_token_idx = #{userTokenIdx}
AND user_type IN ('A')
</update>
<update id="updateAdminLastLoginAt">
/*AdminLoginMapper.updateAdminLastLoginAt*/
UPDATE ALISTLMS.test_user
SET last_login_at = now()
, update_at = now()
WHERE user_idx = #{userIdx}
</update>
<update id="clearAdminRefreshToken">
/*AdminLoginMapper.clearAdminRefreshToken*/
UPDATE ALISTLMS.test_user_token
SET refresh_token = null
, expires_at = null
, updated_at = now()
WHERE user_token_idx = #{userTokenIdx}
AND user_type IN ('A')
</update>
<update id="updateAdminApiKeyLoginRefreshToken">
/*AdminLoginMapper.updateAdminApiKeyLoginRefreshToken*/
UPDATE ALISTLMS.test_user_token
SET refresh_token = #{refreshToken}
, expires_at = #{expiresAt}
, updated_at = now()
WHERE user_token_idx = #{userTokenIdx}
AND user_type IN ('A')
</update>
<select id="selectAdminLoginById" resultType="com.alist.api.modules.admin.auth.vo.AdminLoginVo">
/*AdminLoginMapper.selectAdminLoginById*/
SELECT ATU.user_idx SELECT ATU.user_idx
, ATU.id , ATU.id
, ATU.password , ATU.password
@@ -51,8 +17,9 @@
AND ATUT.user_type IN ('A') AND ATUT.user_type IN ('A')
LIMIT 1 LIMIT 1
</select> </select>
<select id="selectAdminTokenByUserTokenIdx" resultType="com.alist.api.modules.admin.auth.vo.AdminLoginVo">
/*AdminLoginMapper.selectAdminTokenByUserTokenIdx*/ <select id="selectAdminTokenByUserTokenIdx" resultType="com.alist.api.modules.admin.auth.vo.AdminAuthLoginVo">
/*AdminAuthMapper.selectAdminTokenByUserTokenIdx*/
SELECT ATU.user_idx SELECT ATU.user_idx
, ATU.id , ATU.id
, ATUT.user_token_idx , ATUT.user_token_idx
@@ -66,8 +33,9 @@
AND ATU.del_yn = 1 AND ATU.del_yn = 1
LIMIT 1 LIMIT 1
</select> </select>
<select id="selectAdminApiKeyLogin" resultType="com.alist.api.modules.admin.auth.vo.AdminApiKeyLoginVo">
/*AdminLoginMapper.selectAdminApiKeyLogin*/ <select id="selectAdminAuthApiKeyLogin" resultType="com.alist.api.modules.admin.auth.vo.AdminAuthApiKeyLoginVo">
/*AdminAuthMapper.selectAdminAuthApiKeyLogin*/
SELECT ATU.user_idx SELECT ATU.user_idx
, ATU.id , ATU.id
, ATUT.user_token_idx , ATUT.user_token_idx
@@ -80,4 +48,42 @@
AND ATU.del_yn = 1 AND ATU.del_yn = 1
LIMIT 1 LIMIT 1
</select> </select>
<update id="updateAdminRefreshToken">
/*AdminAuthMapper.updateAdminRefreshToken*/
UPDATE ALISTLMS.test_user_token
SET refresh_token = #{refreshToken}
, expires_at = #{expiresAt}
, updated_at = now()
WHERE user_token_idx = #{userTokenIdx}
AND user_type IN ('A')
</update>
<update id="updateAdminLastLoginAt">
/*AdminAuthMapper.updateAdminLastLoginAt*/
UPDATE ALISTLMS.test_user
SET last_login_at = now()
, update_at = now()
WHERE user_idx = #{userIdx}
</update>
<update id="updateClearAdminRefreshToken">
/*AdminAuthMapper.updateClearAdminRefreshToken*/
UPDATE ALISTLMS.test_user_token
SET refresh_token = null
, expires_at = null
, updated_at = now()
WHERE user_token_idx = #{userTokenIdx}
AND user_type IN ('A')
</update>
<update id="updateAdminApiKeyLoginRefreshToken">
/*AdminAuthMapper.updateAdminApiKeyLoginRefreshToken*/
UPDATE ALISTLMS.test_user_token
SET refresh_token = #{refreshToken}
, expires_at = #{expiresAt}
, updated_at = now()
WHERE user_token_idx = #{userTokenIdx}
AND user_type IN ('A')
</update>
</mapper> </mapper>