From 5d3f5dc15da589d940a977f927edb79be567ade1 Mon Sep 17 00:00:00 2001 From: sdw086 Date: Thu, 30 Apr 2026 08:32:03 +0900 Subject: [PATCH] =?UTF-8?q?[admin]=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=95=84=EC=9B=83=20=EC=9E=91=EC=97=85=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/config/MainDataSourceConfig.java | 20 ++- .../com/alist/api/config/SecurityConfig.java | 19 +++ .../config/jwt/JwtAuthenticationFilter.java | 56 +++++-- .../api/config/jwt/JwtTokenProvider.java | 49 +++++- .../admin/auth/AdminAuthController.java | 62 +++++++ .../modules/admin/auth/dto/AdminLoginDto.java | 18 +++ .../admin/auth/form/AdminLoginForm.java | 24 +++ .../admin/auth/mapper/AdminAuthMapper.java | 18 +++ .../admin/auth/service/AdminAuthService.java | 153 ++++++++++++++++++ .../modules/admin/auth/vo/AdminLoginVo.java | 25 +++ src/main/resources/application-local.yaml | 2 +- .../mapper/admin/auth/AdminLoginMapper.xml | 56 +++++++ 12 files changed, 483 insertions(+), 19 deletions(-) create mode 100644 src/main/java/com/alist/api/modules/admin/auth/AdminAuthController.java create mode 100644 src/main/java/com/alist/api/modules/admin/auth/dto/AdminLoginDto.java create mode 100644 src/main/java/com/alist/api/modules/admin/auth/form/AdminLoginForm.java create mode 100644 src/main/java/com/alist/api/modules/admin/auth/mapper/AdminAuthMapper.java create mode 100644 src/main/java/com/alist/api/modules/admin/auth/service/AdminAuthService.java create mode 100644 src/main/java/com/alist/api/modules/admin/auth/vo/AdminLoginVo.java create mode 100644 src/main/resources/mapper/admin/auth/AdminLoginMapper.xml diff --git a/src/main/java/com/alist/api/config/MainDataSourceConfig.java b/src/main/java/com/alist/api/config/MainDataSourceConfig.java index c6d6628..9937986 100644 --- a/src/main/java/com/alist/api/config/MainDataSourceConfig.java +++ b/src/main/java/com/alist/api/config/MainDataSourceConfig.java @@ -14,9 +14,13 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import java.util.Arrays; +import java.util.stream.Stream; + @Configuration @MapperScan( basePackages = "com.alist.api.modules", @@ -51,10 +55,18 @@ public class MainDataSourceConfig { factoryBean.setDataSource(mainDataSource); factoryBean.setTypeAliasesPackage("com.alist.api"); factoryBean.setConfiguration(mybatisConfiguration()); - factoryBean.setMapperLocations( - new PathMatchingResourcePatternResolver() - .getResources("classpath:mapper/*/*.xml") - ); + + PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); + + Resource[] commonMappers = resolver.getResources("classpath:mapper/*/*.xml"); + Resource[] adminMappers = resolver.getResources("classpath:mapper/admin/**/*.xml"); + + Resource[] mapperLocations = Stream.concat( + Arrays.stream(commonMappers), + Arrays.stream(adminMappers) + ).toArray(Resource[]::new); + + factoryBean.setMapperLocations(mapperLocations); return factoryBean.getObject(); } diff --git a/src/main/java/com/alist/api/config/SecurityConfig.java b/src/main/java/com/alist/api/config/SecurityConfig.java index 962cd00..5b5cbb0 100644 --- a/src/main/java/com/alist/api/config/SecurityConfig.java +++ b/src/main/java/com/alist/api/config/SecurityConfig.java @@ -50,6 +50,25 @@ public class SecurityConfig { @Bean @Order(2) + public SecurityFilterChain adminFilterChain( + HttpSecurity http, + JwtAuthenticationFilter jwtAuthenticationFilter + ) throws Exception { + http + .securityMatcher("/admin/**") + .cors(Customizer.withDefaults()) + .csrf(csrf -> csrf.disable()) + .authorizeHttpRequests(auth -> auth + .requestMatchers("/admin/auth/**").permitAll() + .anyRequest().hasRole("ADMIN") + ) + .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); + + return http.build(); + } + + @Bean + @Order(3) public SecurityFilterChain apiFilterChain(HttpSecurity http, JwtAuthenticationFilter jwtAuthenticationFilter) throws Exception { http .cors(Customizer.withDefaults()) diff --git a/src/main/java/com/alist/api/config/jwt/JwtAuthenticationFilter.java b/src/main/java/com/alist/api/config/jwt/JwtAuthenticationFilter.java index 79f0a62..b5f37ed 100644 --- a/src/main/java/com/alist/api/config/jwt/JwtAuthenticationFilter.java +++ b/src/main/java/com/alist/api/config/jwt/JwtAuthenticationFilter.java @@ -7,12 +7,13 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpHeaders; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.web.filter.OncePerRequestFilter; import java.io.IOException; -import java.util.Collections; +import java.util.List; public class JwtAuthenticationFilter extends OncePerRequestFilter { private final JwtTokenProvider jwtTokenProvider; @@ -25,25 +26,50 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { try { - String token = resolveToken(request); + String requestUri = request.getRequestURI(); + boolean adminRequest = requestUri.startsWith("/admin/"); + String token = resolveToken(request, adminRequest); if (token != null && jwtTokenProvider.validateToken(token)) { - String userId = jwtTokenProvider.getUserTokenIdx(token); + String principal = jwtTokenProvider.getUserTokenIdx(token); + String role = jwtTokenProvider.getRole(token); + String scope = jwtTokenProvider.getScope(token); + String tokenType = jwtTokenProvider.getTokenType(token); - UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userId, null, Collections.emptyList()); + if (adminRequest) { + if (!"ADMIN".equals(scope) || !"ACCESS".equals(tokenType) || !"ADMIN".equals(role)) { + SecurityContextHolder.clearContext(); + response.sendError(HttpServletResponse.SC_FORBIDDEN, "Admin token required"); + return; + } + } else { + if ("ADMIN".equals(scope) || "UPLOAD".equals(scope) || !"ACCESS".equals(tokenType)) { + SecurityContextHolder.clearContext(); + response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access token required"); + return; + } + } + + UsernamePasswordAuthenticationToken authentication = + new UsernamePasswordAuthenticationToken( + principal, + null, + role == null + ? List.of() + : List.of(new SimpleGrantedAuthority("ROLE_" + role)) + ); authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(authentication); } } catch (Exception e) { SecurityContextHolder.clearContext(); - // 로깅은 여기서 해도 됨 (SLF4J) } filterChain.doFilter(request, response); } - private String resolveToken(HttpServletRequest request) { + private String resolveToken(HttpServletRequest request, boolean adminRequest) { // 1) Authorization: Bearer xxx 우선 String bearer = request.getHeader(HttpHeaders.AUTHORIZATION); if (bearer != null && bearer.startsWith("Bearer ")) { @@ -55,13 +81,17 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { // 2) 쿠키 fallback (브라우저용) Cookie[] cookies = request.getCookies(); - if (cookies != null) { - for (Cookie cookie : cookies) { - if ("accessToken".equals(cookie.getName())) { - String token = cookie.getValue(); - if (token != null && !token.isBlank()) { - return token.trim(); - } + if (cookies == null) { + return null; + } + + String cookieName = adminRequest ? "adminAccessToken" : "accessToken"; + + for (Cookie cookie : cookies) { + if (cookieName.equals(cookie.getName())) { + String token = cookie.getValue(); + if (token != null && !token.isBlank()) { + return token.trim(); } } } diff --git a/src/main/java/com/alist/api/config/jwt/JwtTokenProvider.java b/src/main/java/com/alist/api/config/jwt/JwtTokenProvider.java index a9a8449..babaa80 100644 --- a/src/main/java/com/alist/api/config/jwt/JwtTokenProvider.java +++ b/src/main/java/com/alist/api/config/jwt/JwtTokenProvider.java @@ -34,6 +34,7 @@ public class JwtTokenProvider { return Jwts.builder() .setSubject(userId) + .claim("tokenType", "ACCESS") .setIssuedAt(now) .setExpiration(expiry) .signWith(secretKey, SignatureAlgorithm.HS256) @@ -48,6 +49,7 @@ public class JwtTokenProvider { return Jwts.builder() .setSubject(String.valueOf(userTokenIdx)) .claim("role", role) + .claim("tokenType", "ACCESS") .setIssuedAt(Date.from(now)) .setExpiration(Date.from(expiry)) .signWith(secretKey, SignatureAlgorithm.HS256) @@ -61,6 +63,7 @@ public class JwtTokenProvider { return Jwts.builder() .setSubject(String.valueOf(userTokenIdx)) + .claim("tokenType", "REFRESH") .setIssuedAt(Date.from(now)) .setExpiration(Date.from(expiry)) .signWith(secretKey, SignatureAlgorithm.HS256) @@ -90,7 +93,6 @@ public class JwtTokenProvider { .getBody(); } - /* 업로드 전용 토큰*/ public String createUploadToken(long userTokenIdx) { Instant now = Instant.now(); @@ -114,4 +116,49 @@ public class JwtTokenProvider { } } + public String createAdminAccessToken(long userTokenIdx) { + Instant now = Instant.now(); + Instant expiry = now.plusSeconds(jwtProperties.getAccessTokenValiditySeconds()); + + return Jwts.builder() + .setSubject(String.valueOf(userTokenIdx)) + .claim("role", "ADMIN") + .claim("scope", "ADMIN") + .claim("tokenType", "ACCESS") + .setIssuedAt(Date.from(now)) + .setExpiration(Date.from(expiry)) + .signWith(secretKey, SignatureAlgorithm.HS256) + .compact(); + } + + public String createAdminRefreshToken(long userTokenIdx) { + Instant now = Instant.now(); + Instant expiry = now.plusSeconds(jwtProperties.getRefreshTokenValiditySeconds()); + + return Jwts.builder() + .setSubject(String.valueOf(userTokenIdx)) + .claim("role", "ADMIN") + .claim("scope", "ADMIN") + .claim("tokenType", "REFRESH") + .setIssuedAt(Date.from(now)) + .setExpiration(Date.from(expiry)) + .signWith(secretKey, SignatureAlgorithm.HS256) + .compact(); + } + + public Claims getClaims(String token) { + return parseClaims(token); + } + + public String getRole(String token) { + return parseClaims(token).get("role", String.class); + } + + public String getScope(String token) { + return parseClaims(token).get("scope", String.class); + } + + public String getTokenType(String token) { + return parseClaims(token).get("tokenType", String.class); + } } diff --git a/src/main/java/com/alist/api/modules/admin/auth/AdminAuthController.java b/src/main/java/com/alist/api/modules/admin/auth/AdminAuthController.java new file mode 100644 index 0000000..c081302 --- /dev/null +++ b/src/main/java/com/alist/api/modules/admin/auth/AdminAuthController.java @@ -0,0 +1,62 @@ +package com.alist.api.modules.admin.auth; + +import com.alist.api.common.response.ApiResponse; +import com.alist.api.common.response.ApiResponseCode; +import com.alist.api.modules.admin.auth.form.AdminLoginForm; +import com.alist.api.modules.admin.auth.service.AdminAuthService; +import com.alist.api.modules.admin.auth.vo.AdminLoginVo; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +@RestController +@RequestMapping("/admin/auth") +public class AdminAuthController { + + private final AdminAuthService adminAuthService; + + public AdminAuthController(AdminAuthService adminAuthService) { + this.adminAuthService = adminAuthService; + } + + @PostMapping("/login") + public ResponseEntity> adminLogin( + @Valid @RequestBody AdminLoginForm adminLoginForm + , HttpServletResponse response + ) { + AdminLoginVo result = adminAuthService.adminLogin(adminLoginForm.toAdminLoginDto(), response); + + if (result.getResultCode() == 2003) { + return ApiResponse.entity(result, ApiResponseCode.CODE_2003); + } + + return ApiResponse.entity(result, ApiResponseCode.CODE_2001, "관리자 로그인"); + } + + @PostMapping("/refresh") + public ResponseEntity>> refresh( + @CookieValue(name = "adminRefreshToken", required = false) String refreshToken, + HttpServletResponse response + ) { + AdminLoginVo result = adminAuthService.adminRefresh(refreshToken, response); + + if (result == null) { + return ApiResponse.entity(Map.of("refreshed", false), ApiResponseCode.CODE_401); + } + + return ApiResponse.entity(Map.of("refreshed", true), ApiResponseCode.CODE_200); + } + + @PostMapping("/logout") + public ResponseEntity>> logout( + @CookieValue(name = "adminRefreshToken", required = false) String refreshToken, + HttpServletResponse response + ) { + adminAuthService.adminLogout(refreshToken, response); + + return ApiResponse.entity(Map.of("loggedOut", true), ApiResponseCode.CODE_200); + } +} diff --git a/src/main/java/com/alist/api/modules/admin/auth/dto/AdminLoginDto.java b/src/main/java/com/alist/api/modules/admin/auth/dto/AdminLoginDto.java new file mode 100644 index 0000000..0788d5a --- /dev/null +++ b/src/main/java/com/alist/api/modules/admin/auth/dto/AdminLoginDto.java @@ -0,0 +1,18 @@ +package com.alist.api.modules.admin.auth.dto; + +import lombok.Getter; +import lombok.Setter; + +import java.time.Instant; + +@Setter +@Getter +public class AdminLoginDto { + private String id; + private String password; + + private Integer userIdx; + private Integer userTokenIdx; + private String refreshToken; + private Instant expiresAt; +} diff --git a/src/main/java/com/alist/api/modules/admin/auth/form/AdminLoginForm.java b/src/main/java/com/alist/api/modules/admin/auth/form/AdminLoginForm.java new file mode 100644 index 0000000..de99e3f --- /dev/null +++ b/src/main/java/com/alist/api/modules/admin/auth/form/AdminLoginForm.java @@ -0,0 +1,24 @@ +package com.alist.api.modules.admin.auth.form; + +import com.alist.api.modules.admin.auth.dto.AdminLoginDto; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class AdminLoginForm { + @NotBlank + private String id; + + @NotBlank + private String password; + + public AdminLoginDto toAdminLoginDto() { + AdminLoginDto adminLoginDto = new AdminLoginDto(); + adminLoginDto.setId(id.trim()); + adminLoginDto.setPassword(password); + + return adminLoginDto; + } +} diff --git a/src/main/java/com/alist/api/modules/admin/auth/mapper/AdminAuthMapper.java b/src/main/java/com/alist/api/modules/admin/auth/mapper/AdminAuthMapper.java new file mode 100644 index 0000000..7797e98 --- /dev/null +++ b/src/main/java/com/alist/api/modules/admin/auth/mapper/AdminAuthMapper.java @@ -0,0 +1,18 @@ +package com.alist.api.modules.admin.auth.mapper; + +import com.alist.api.modules.admin.auth.dto.AdminLoginDto; +import com.alist.api.modules.admin.auth.vo.AdminLoginVo; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface AdminAuthMapper { + AdminLoginVo selectAdminLoginById(String id); + + void updateAdminRefreshToken(AdminLoginDto adminLoginDto); + + void updateAdminLastLoginAt(Integer userIdx); + + AdminLoginVo selectAdminTokenByUserTokenIdx(Integer userTokenIdx); + + void clearAdminRefreshToken(Integer userTokenIdx); +} diff --git a/src/main/java/com/alist/api/modules/admin/auth/service/AdminAuthService.java b/src/main/java/com/alist/api/modules/admin/auth/service/AdminAuthService.java new file mode 100644 index 0000000..400ab6f --- /dev/null +++ b/src/main/java/com/alist/api/modules/admin/auth/service/AdminAuthService.java @@ -0,0 +1,153 @@ +package com.alist.api.modules.admin.auth.service; + +import com.alist.api.common.utils.SessionUtil; +import com.alist.api.config.jwt.JwtTokenProvider; +import com.alist.api.modules.admin.auth.dto.AdminLoginDto; +import com.alist.api.modules.admin.auth.mapper.AdminAuthMapper; +import com.alist.api.modules.admin.auth.vo.AdminLoginVo; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.Instant; + +@Service +public class AdminAuthService { + @Value("${cookie.secure}") + private boolean cookieSecure; + + @Value("${cookie.domain:}") + private String cookieDomain; + + @Value("${cookie.same-site:Lax}") + private String cookieSameSite; + + @Value("${jwt.access-token-validity-seconds}") + private long accessTokenValiditySeconds; + + @Value("${jwt.refresh-token-validity-seconds}") + private long refreshTokenValiditySeconds; + + private final AdminAuthMapper adminAuthMapper; + private final JwtTokenProvider jwtTokenProvider; + private final PasswordEncoder passwordEncoder; + + public AdminAuthService(AdminAuthMapper adminAuthMapper, JwtTokenProvider jwtTokenProvider, PasswordEncoder passwordEncoder) { + this.adminAuthMapper = adminAuthMapper; + this.jwtTokenProvider = jwtTokenProvider; + this.passwordEncoder = passwordEncoder; + } + + @Transactional + public AdminLoginVo adminLogin(AdminLoginDto adminLoginDto, HttpServletResponse response) { + AdminLoginVo result = new AdminLoginVo(); + AdminLoginVo adminLoginVo = adminAuthMapper.selectAdminLoginById(adminLoginDto.getId()); + + if (adminLoginVo == null) { + result.setResultCode(2003); + result.setLogin(false); + return result; + } + + if (!passwordEncoder.matches(adminLoginDto.getPassword(), adminLoginVo.getPassword())) { + result.setResultCode(2003); + result.setLogin(false); + return result; + } + + String accessToken = jwtTokenProvider.createAdminAccessToken(adminLoginVo.getUserTokenIdx()); + String refreshToken = jwtTokenProvider.createAdminRefreshToken(adminLoginVo.getUserTokenIdx()); + + adminLoginDto.setUserIdx(adminLoginVo.getUserIdx()); + adminLoginDto.setUserTokenIdx(adminLoginVo.getUserTokenIdx()); + adminLoginDto.setRefreshToken(refreshToken); + adminLoginDto.setExpiresAt(Instant.now().plusSeconds(refreshTokenValiditySeconds)); + + adminAuthMapper.updateAdminRefreshToken(adminLoginDto); + adminAuthMapper.updateAdminLastLoginAt(adminLoginDto.getUserIdx()); + + SessionUtil.addTokenCookie(response,"adminAccessToken", accessToken, cookieDomain, cookieSecure, cookieSameSite, accessTokenValiditySeconds); + SessionUtil.addTokenCookie(response,"adminRefreshToken", refreshToken, cookieDomain, cookieSecure, cookieSameSite, refreshTokenValiditySeconds); + + adminLoginVo.setResultCode(2001); + adminLoginVo.setLogin(true); + return adminLoginVo; + } + + public AdminLoginVo adminRefresh(String refreshToken, HttpServletResponse response) { + if (refreshToken == null || !jwtTokenProvider.validateToken(refreshToken)) { + return null; + } + + String role = jwtTokenProvider.getRole(refreshToken); + String scope = jwtTokenProvider.getScope(refreshToken); + String tokenType = jwtTokenProvider.getTokenType(refreshToken); + + if (!"ADMIN".equals(role) || !"ADMIN".equals(scope) || !"REFRESH".equals(tokenType)) { + return null; + } + + Integer userTokenIdx; + + try { + userTokenIdx = Integer.parseInt(jwtTokenProvider.getUserTokenIdx(refreshToken)); + } catch (NumberFormatException e) { + return null; + } + + AdminLoginVo adminToken = adminAuthMapper.selectAdminTokenByUserTokenIdx(userTokenIdx); + if (adminToken == null || adminToken.getRefreshToken() == null) { + return null; + } + + if (!refreshToken.equals(adminToken.getRefreshToken())) { + return null; + } + + String newAccessToken = jwtTokenProvider.createAdminAccessToken(userTokenIdx); + String newRefreshToken = jwtTokenProvider.createAdminRefreshToken(userTokenIdx); + + AdminLoginDto adminLoginDto = new AdminLoginDto(); + + adminLoginDto.setUserTokenIdx(userTokenIdx); + adminLoginDto.setRefreshToken(newRefreshToken); + adminLoginDto.setExpiresAt(Instant.now().plusSeconds(refreshTokenValiditySeconds)); + + adminAuthMapper.updateAdminRefreshToken(adminLoginDto); + + SessionUtil.addTokenCookie(response, "adminAccessToken", newAccessToken, cookieDomain, cookieSecure, cookieSameSite, accessTokenValiditySeconds); + SessionUtil.addTokenCookie(response, "adminRefreshToken", newRefreshToken, cookieDomain, cookieSecure, cookieSameSite, refreshTokenValiditySeconds); + + adminToken.setResultCode(2001); + return adminToken; + } + + public void adminLogout(String refreshToken, HttpServletResponse response) { + clearAdminRefreshToken(refreshToken); + + SessionUtil.expireCookie(response, "adminAccessToken", cookieDomain, cookieSecure, cookieSameSite); + SessionUtil.expireCookie(response, "adminRefreshToken", cookieDomain, cookieSecure, cookieSameSite); + } + + private void clearAdminRefreshToken(String refreshToken) { + if (refreshToken == null || !jwtTokenProvider.validateToken(refreshToken)) { + return; + } + + String role = jwtTokenProvider.getRole(refreshToken); + String scope = jwtTokenProvider.getScope(refreshToken); + String tokenType = jwtTokenProvider.getTokenType(refreshToken); + + if (!"ADMIN".equals(role) || !"ADMIN".equals(scope) || !"REFRESH".equals(tokenType)) { + return; + } + + try { + Integer userTokenIdx = Integer.parseInt(jwtTokenProvider.getUserTokenIdx(refreshToken)); + adminAuthMapper.clearAdminRefreshToken(userTokenIdx); + } catch (NumberFormatException ignored) { + } + } +} diff --git a/src/main/java/com/alist/api/modules/admin/auth/vo/AdminLoginVo.java b/src/main/java/com/alist/api/modules/admin/auth/vo/AdminLoginVo.java new file mode 100644 index 0000000..306b3e7 --- /dev/null +++ b/src/main/java/com/alist/api/modules/admin/auth/vo/AdminLoginVo.java @@ -0,0 +1,25 @@ +package com.alist.api.modules.admin.auth.vo; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class AdminLoginVo { + private boolean isLogin; + private Integer userIdx; + private String id; + + @JsonIgnore + private String password; + + @JsonIgnore + private Integer userTokenIdx; + + @JsonIgnore + private String refreshToken; + + @JsonIgnore + private int resultCode; +} diff --git a/src/main/resources/application-local.yaml b/src/main/resources/application-local.yaml index 7c5ca15..b124463 100644 --- a/src/main/resources/application-local.yaml +++ b/src/main/resources/application-local.yaml @@ -46,7 +46,7 @@ jwt: cookie: secure: false # (HTTP) -> false - domain: api-alist.pjt.kr # (HTTP) -> 비워두세요 + domain: # (HTTP) -> 비워두세요 name: ALIST_SSO same-site: Lax # (HTTP) -> Lax diff --git a/src/main/resources/mapper/admin/auth/AdminLoginMapper.xml b/src/main/resources/mapper/admin/auth/AdminLoginMapper.xml new file mode 100644 index 0000000..44d22f7 --- /dev/null +++ b/src/main/resources/mapper/admin/auth/AdminLoginMapper.xml @@ -0,0 +1,56 @@ + + + + + + /*AdminLoginMapper.updateAdminRefreshToken*/ + UPDATE ALISTLMS.test_user_token + SET refresh_token = #{refreshToken} + , expires_at = #{expiresAt} + , updated_at = now() + WHERE user_token_idx = #{userTokenIdx} + AND user_role = 'admin' + + + /*AdminLoginMapper.updateAdminLastLoginAt*/ + UPDATE ALISTLMS.test_user + SET last_login_at = now() + , update_at = now() + WHERE user_idx = #{userIdx} + + + /*AdminLoginMapper.clearAdminRefreshToken*/ + UPDATE ALISTLMS.test_user_token + SET refresh_token = null + , expires_at = null + , updated_at = now() + WHERE user_token_idx = #{userTokenIdx} + AND user_role = 'admin' + + + +