Merge branch 'be/refactor/jwt' into 'be/develop'

Refactor: reissue API 오류 해결

See merge request s11-s-project/S11P21S002!18
This commit is contained in:
김태수 2024-08-29 15:33:28 +09:00
commit effd47ba61
13 changed files with 150 additions and 89 deletions

View File

@ -1,13 +1,17 @@
package com.worlabel.domain.auth.controller; package com.worlabel.domain.auth.controller;
import com.worlabel.domain.auth.entity.dto.JwtToken; import com.worlabel.domain.auth.entity.dto.JwtToken;
import com.worlabel.domain.auth.repository.AuthCacheRepository; import com.worlabel.domain.auth.entity.dto.AccessTokenResponse;
import com.worlabel.domain.auth.service.AuthService; import com.worlabel.domain.auth.service.AuthService;
import com.worlabel.domain.auth.service.JwtTokenService; import com.worlabel.domain.auth.service.JwtTokenService;
import com.worlabel.global.annotation.CurrentUser; import com.worlabel.global.annotation.CurrentUser;
import com.worlabel.global.config.swagger.SwaggerApiError;
import com.worlabel.global.config.swagger.SwaggerApiSuccess;
import com.worlabel.global.exception.CustomException; import com.worlabel.global.exception.CustomException;
import com.worlabel.global.exception.ErrorCode; import com.worlabel.global.exception.ErrorCode;
import com.worlabel.global.response.SuccessResponse; import com.worlabel.global.response.SuccessResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.Cookie; import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
@ -21,35 +25,38 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays; import java.util.Arrays;
@Slf4j @Slf4j
@RestController @RestController
@RequiredArgsConstructor @RequiredArgsConstructor
@Tag(name = "인증/인가 관련 API")
@RequestMapping("/api/auth") @RequestMapping("/api/auth")
public class AuthController { public class AuthController {
private final AuthService authService;
private final AuthCacheRepository authCacheRepository;
private final JwtTokenService jwtTokenService;
@Value("${auth.refreshTokenExpiry}") @Value("${auth.refreshTokenExpiry}")
long refreshExpiry; long refreshExpiry;
// TODO: 리이슈 처리, 액세스 어떻게 받았는지 물어보기 private final AuthService authService;
private final JwtTokenService jwtTokenService;
@Operation(summary = "JWT 토큰 재발급", description = "Refresh Token을 확인하여 JWT 토큰 재발급")
@SwaggerApiSuccess(description = "Return Access Token")
@SwaggerApiError({ErrorCode.INVALID_TOKEN, ErrorCode.USER_ALREADY_SIGN_OUT, ErrorCode.REFRESH_TOKEN_EXPIRED, ErrorCode.INVALID_REFRESH_TOKEN})
@PostMapping("/reissue") @PostMapping("/reissue")
public SuccessResponse<String> reissue( public SuccessResponse<AccessTokenResponse> reissue(
HttpServletRequest request, HttpServletRequest request,
HttpServletResponse response HttpServletResponse response
) { ) {
log.debug("reissue request");
String refresh = parseRefreshCookie(request); String refresh = parseRefreshCookie(request);
log.info("reissue :{}", refresh);
try { try {
JwtToken newToken = authService.reissue(refresh); JwtToken newToken = authService.reissue(refresh);
log.debug("새로운 토큰 발급 성공");
int id = jwtTokenService.parseId(newToken.getAccessToken()); int id = jwtTokenService.parseId(newToken.getAccessToken());
log.debug("{}",id);
response.addCookie(createCookie(newToken.getRefreshToken())); response.addCookie(createCookie(newToken.getRefreshToken()));
authCacheRepository.save(id, newToken.getRefreshToken(), refreshExpiry); authService.saveRefreshToken(id, newToken.getRefreshToken(),refreshExpiry);
return SuccessResponse.of(newToken.getAccessToken());
return SuccessResponse.of(AccessTokenResponse.from(newToken.getAccessToken()));
} catch (CustomException e) { } catch (CustomException e) {
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
@ -57,15 +64,10 @@ public class AuthController {
} }
} }
private Cookie createCookie(String value) { // TODO: Member 완성 구현
Cookie cookie = new Cookie("refreshToken", value); @Operation(summary = "로그인 중인 사용자 정보를 반환", description = "현재 로그인중인 사용자의 정보를 반환합니다.")
cookie.setMaxAge((int) (refreshExpiry / 1000)); @SwaggerApiSuccess(description = "Return Member Info")
cookie.setPath("/"); @SwaggerApiError({ErrorCode.INVALID_TOKEN, ErrorCode.USER_ALREADY_SIGN_OUT, ErrorCode.REFRESH_TOKEN_EXPIRED, ErrorCode.INVALID_REFRESH_TOKEN})
cookie.setHttpOnly(true);
// cookie.setSecure(true); // 배포 HTTPS에서 사용
return cookie;
}
@GetMapping("/user-info") @GetMapping("/user-info")
public SuccessResponse<Integer> getMemberInfo(@CurrentUser Integer currentMember){ public SuccessResponse<Integer> getMemberInfo(@CurrentUser Integer currentMember){
return SuccessResponse.of(currentMember); return SuccessResponse.of(currentMember);
@ -77,9 +79,18 @@ public class AuthController {
return Arrays.stream(cookies) return Arrays.stream(cookies)
.filter(cookie -> "refreshToken".equals(cookie.getName())) .filter(cookie -> "refreshToken".equals(cookie.getName()))
.findFirst() .findFirst()
.map(Cookie::getValue) .map(cookie -> cookie.getValue().trim())
.orElse(null); .orElse(null);
} }
return null; return null;
} }
private Cookie createCookie(String value) {
Cookie cookie = new Cookie("refreshToken", value);
cookie.setMaxAge((int) (refreshExpiry / 1000));
cookie.setPath("/");
cookie.setHttpOnly(true);
// cookie.setSecure(true); // 배포 HTTPS에서 사용
return cookie;
}
} }

View File

@ -17,7 +17,7 @@ public class CustomOAuth2User implements OAuth2User {
private transient final AuthMemberDto authMember; private transient final AuthMemberDto authMember;
public CustomOAuth2User(Member member) { public CustomOAuth2User(Member member) {
authMember = AuthMemberDto.of(member); authMember = AuthMemberDto.from(member);
} }
@Override @Override

View File

@ -0,0 +1,19 @@
package com.worlabel.domain.auth.entity.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Schema(name = "리프레시 토큰 응답 dto", description = "리프레시 토큰 응답 dto")
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class AccessTokenResponse {
@Schema(description = "액세스 토큰", example = "")
private String accessToken;
public static AccessTokenResponse from(String accessToken) {
return new AccessTokenResponse(accessToken);
}
}

View File

@ -1,22 +1,24 @@
package com.worlabel.domain.auth.entity.dto; package com.worlabel.domain.auth.entity.dto;
import com.worlabel.domain.member.entity.Member; import com.worlabel.domain.member.entity.Member;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.ToString; import lombok.ToString;
@Getter @Getter
@ToString @ToString
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class AuthMemberDto { public class AuthMemberDto {
private int id; private int id;
private String email; private String email;
private String role; private String role;
public static AuthMemberDto of(Member member) { public static AuthMemberDto from(Member member) {
AuthMemberDto authMemberDto = new AuthMemberDto(); return new AuthMemberDto(member.getId(), member.getEmail(), member.getRole().toString());
authMemberDto.id = member.getId(); }
authMemberDto.email = member.getEmail();
authMemberDto.role = member.getRole().toString();
return authMemberDto; public static AuthMemberDto of(int id, String email, String role) {
return new AuthMemberDto(id, email, role);
} }
} }

View File

@ -1,11 +1,16 @@
package com.worlabel.domain.auth.entity.dto; package com.worlabel.domain.auth.entity.dto;
import lombok.AccessLevel;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor(access = AccessLevel.PRIVATE)
public class JwtToken { public class JwtToken {
private String accessToken; private String accessToken;
private String refreshToken; private String refreshToken;
public static JwtToken of(String accessToken, String refreshToken){
return new JwtToken(accessToken, refreshToken);
}
} }

View File

@ -1,16 +0,0 @@
package com.worlabel.domain.auth.entity.dto;
import lombok.Getter;
@Getter
public class LoginMember {
private int id;
private String email;
public static LoginMember of(int id, String email) {
LoginMember member = new LoginMember();
member.id = id;
member.email = email;
return member;
}
}

View File

@ -15,14 +15,23 @@ public class AuthCacheRepository {
private final RedisTemplate<String, Object> redisTemplate; private final RedisTemplate<String, Object> redisTemplate;
public void save(int memberId, String token, Long expiredTime) { /**
redisTemplate.opsForValue().set(CacheKey.authenticationKey(memberId), String.valueOf(token), expiredTime, TimeUnit.MILLISECONDS); * 리프레시 토큰 저장
*/
public void save(int memberId, String refreshToken, Long expiredTime) {
redisTemplate.opsForValue().set(CacheKey.authenticationKey(memberId), String.valueOf(refreshToken), expiredTime, TimeUnit.MILLISECONDS);
} }
/**
* 리프레시 토큰 반환
*/
public String find(int memberId) { public String find(int memberId) {
return (String) redisTemplate.opsForValue().get(CacheKey.authenticationKey(memberId)); return (String) redisTemplate.opsForValue().get(CacheKey.authenticationKey(memberId));
} }
/**
* 리프레시 토큰 삭제
*/
public void delete(int memberId){ public void delete(int memberId){
redisTemplate.delete(CacheKey.authenticationKey(memberId)); redisTemplate.delete(CacheKey.authenticationKey(memberId));
} }

View File

@ -7,6 +7,7 @@ import com.worlabel.global.exception.ErrorCode;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.Objects; import java.util.Objects;
@ -14,17 +15,26 @@ import java.util.Objects;
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class AuthService { public class AuthService {
private final JwtTokenService jwtTokenService; private final JwtTokenService jwtTokenService;
private final AuthCacheRepository authCacheRepository; private final AuthCacheRepository authCacheRepository;
/**
* JWT 토큰 재발급
*/
public JwtToken reissue(String refreshToken) throws Exception { public JwtToken reissue(String refreshToken) throws Exception {
int id = jwtTokenService.parseId(refreshToken); int id = jwtTokenService.parseId(refreshToken);
Object redisRefreshToken = authCacheRepository.find(id); String redisRefreshToken = authCacheRepository.find(id);
log.debug("{} == {} ",redisRefreshToken,refreshToken); if(!refreshToken.equals(redisRefreshToken)){
if(!Objects.equals(refreshToken, redisRefreshToken)){
throw new CustomException(ErrorCode.USER_ALREADY_SIGN_OUT); throw new CustomException(ErrorCode.USER_ALREADY_SIGN_OUT);
} }
return jwtTokenService.generateTokenByRefreshToken(refreshToken); return jwtTokenService.generateTokenByRefreshToken(refreshToken);
} }
/**
* 레디에 리프레시 토큰 저장
*/
public void saveRefreshToken(int id, String refreshToken,Long expiredTime) {
authCacheRepository.save(id, refreshToken, expiredTime);
}
} }

View File

@ -2,10 +2,13 @@ package com.worlabel.domain.auth.service;
import com.worlabel.domain.auth.entity.CustomOAuth2User; import com.worlabel.domain.auth.entity.CustomOAuth2User;
import com.worlabel.domain.auth.entity.dto.JwtToken; import com.worlabel.domain.auth.entity.dto.JwtToken;
import com.worlabel.global.exception.CustomException;
import com.worlabel.global.exception.ErrorCode;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts; import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException; import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.security.SignatureException;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
@ -15,8 +18,11 @@ import org.springframework.stereotype.Service;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -27,6 +33,7 @@ public class JwtTokenService {
private final SecretKey secretKey; private final SecretKey secretKey;
private final Long tokenExpiration; private final Long tokenExpiration;
private final Long refreshTokenExpiration; private final Long refreshTokenExpiration;
private Key key ;
public JwtTokenService( public JwtTokenService(
@Value("${spring.jwt.secret}") String key, @Value("${spring.jwt.secret}") String key,
@ -46,15 +53,24 @@ public class JwtTokenService {
} }
public JwtToken generateTokenByRefreshToken(String refreshToken) throws Exception { public JwtToken generateTokenByRefreshToken(String refreshToken) throws Exception {
if (!isTokenExpired(refreshToken) && isRefreshToken(refreshToken)) { log.debug("생성");
if (isTokenExpired(refreshToken)) {
throw new CustomException(ErrorCode.REFRESH_TOKEN_EXPIRED);
}
if (!isRefreshToken(refreshToken)) {
throw new CustomException(ErrorCode.INVALID_REFRESH_TOKEN);
}
log.debug("유효성 통과");
Claims claims = parseClaims(refreshToken); Claims claims = parseClaims(refreshToken);
String username = claims.getSubject(); String username = claims.getSubject();
int memberId = claims.get("id", Integer.class); int memberId = claims.get("id", Integer.class);
List<String> authorities = parseAuthorities(refreshToken).stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()); List<String> authorities = parseAuthorities(refreshToken).stream().map(GrantedAuthority::getAuthority).toList();
return generateToken(username, memberId, authorities); return generateToken(username, memberId, authorities);
} }
throw new Exception("유효하지 않은 토큰입니다.");
}
private JwtToken generateToken(String username, int memberId, List<String> authorities) { private JwtToken generateToken(String username, int memberId, List<String> authorities) {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
@ -62,12 +78,17 @@ public class JwtTokenService {
Date accessTokenExpire = new Date(now + tokenExpiration); Date accessTokenExpire = new Date(now + tokenExpiration);
Date refreshTokenExpire = new Date(now + refreshTokenExpiration); Date refreshTokenExpire = new Date(now + refreshTokenExpiration);
log.debug("액세스 만료 시간 : {}", accessTokenExpire.getTime());
log.debug("리프레시 만료 시간 : {}", refreshTokenExpire.getTime());
String accessToken = Jwts.builder() String accessToken = Jwts.builder()
.subject(username) .subject(username)
.claim("type", "access") .claim("type", "access")
.claim("id", memberId) .claim("id", memberId)
.claim("authorities", authorities) // 권한 정보 추가 .claim("authorities", authorities) // 권한 정보 추가
.issuedAt(new Date(now))
.expiration(accessTokenExpire) .expiration(accessTokenExpire)
.claim("jti", UUID.randomUUID().toString())
.signWith(secretKey) .signWith(secretKey)
.compact(); .compact();
@ -76,12 +97,13 @@ public class JwtTokenService {
.claim("type", "refresh") .claim("type", "refresh")
.claim("id", memberId) .claim("id", memberId)
.claim("authorities", authorities) // 권한 정보 추가 .claim("authorities", authorities) // 권한 정보 추가
.issuedAt(new Date(now))
.expiration(refreshTokenExpire) .expiration(refreshTokenExpire)
.claim("jti", UUID.randomUUID().toString())
.signWith(secretKey) .signWith(secretKey)
.compact(); .compact();
log.debug("액세스 발급: {}",accessToken); return JwtToken.of(accessToken, refreshToken);
return new JwtToken(accessToken, refreshToken);
} }
public String parseUsername(String token) throws Exception { public String parseUsername(String token) throws Exception {
@ -101,15 +123,8 @@ public class JwtTokenService {
} }
// 토큰 만료 여부 확인 // 토큰 만료 여부 확인
public boolean isTokenExpired(String token){ public boolean isTokenExpired(String token) throws Exception {
try{ return parseClaims(token) == null;
Claims claims = parseClaims(token);
return claims.getExpiration().before(new Date());
}catch (ExpiredJwtException e) {
return true; // 만료된 토큰
} catch (Exception e) {
return false; // 다른 오류일 경우
}
} }
public boolean isRefreshToken(String token) { public boolean isRefreshToken(String token) {
@ -142,11 +157,12 @@ public class JwtTokenService {
.getPayload(); .getPayload();
} catch (ExpiredJwtException e) { } catch (ExpiredJwtException e) {
message = "유효기간이 만료된 토큰입니다."; message = "유효기간이 만료된 토큰입니다.";
}catch (MalformedJwtException e){ } catch (MalformedJwtException | SignatureException e) {
message = "잘못된 형식의 토큰입니다."; message = "잘못된 형식의 토큰입니다.";
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
message = "잘못된 인자입니다."; message = "잘못된 인자입니다.";
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace();
message = "토큰 파싱 중 에러가 발생했습니다."; message = "토큰 파싱 중 에러가 발생했습니다.";
} }
throw new Exception(message); throw new Exception(message);

View File

@ -7,9 +7,9 @@ import lombok.Getter;
import java.util.List; import java.util.List;
@Schema(name = "워크스페이스 목록 응답 dto", description = "워크스페이스 목록 응답 DTO")
@Getter @Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE) @AllArgsConstructor(access = AccessLevel.PRIVATE)
@Schema(name = "워크스페이스 목록 응답 dto", description = "워크스페이스 목록 응답 DTO")
public class WorkspaceResponses { public class WorkspaceResponses {
@Schema(description = "워크스페이스 목록", example = "") @Schema(description = "워크스페이스 목록", example = "")

View File

@ -35,13 +35,14 @@ public class SecurityConfig {
@Bean @Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// HTTP Basic 인증 방식 비활성화 // HTTP Basic 인증 방식 비활성화
http. http.
httpBasic((auth) -> auth.disable()); httpBasic((auth) -> auth.disable());
// CSRF 비활성화 // CSRF 비활성화
http http
.csrf((auth) -> auth.disable()); .csrf((auth) -> auth.disable());
// Form 로그인 방식 비활성화 // Form 로그인 방식 비활성화
http http
.formLogin((auth) -> auth.disable()); .formLogin((auth) -> auth.disable());
@ -60,11 +61,10 @@ public class SecurityConfig {
.accessDeniedHandler(authenticationDeniedHandler) .accessDeniedHandler(authenticationDeniedHandler)
); );
// 경로별 인가 작업 // 경로별 인가 작업
http http
.authorizeHttpRequests(auth->auth .authorizeHttpRequests(auth->auth
.requestMatchers("/api/**").authenticated() .requestMatchers("/api/auth/reissue").permitAll()
.anyRequest().authenticated()); .anyRequest().authenticated());
// OAuth2 // OAuth2

View File

@ -1,6 +1,6 @@
package com.worlabel.global.filter; package com.worlabel.global.filter;
import com.worlabel.domain.auth.entity.dto.LoginMember; import com.worlabel.domain.auth.entity.dto.AuthMemberDto;
import com.worlabel.domain.auth.service.JwtTokenService; import com.worlabel.domain.auth.service.JwtTokenService;
import jakarta.servlet.FilterChain; import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException; import jakarta.servlet.ServletException;
@ -36,9 +36,13 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
if (StringUtils.hasText(token) && !jwtTokenService.isTokenExpired(token) && jwtTokenService.isAccessToken(token)) { if (StringUtils.hasText(token) && !jwtTokenService.isTokenExpired(token) && jwtTokenService.isAccessToken(token)) {
String name = jwtTokenService.parseUsername(token); String name = jwtTokenService.parseUsername(token);
int id = jwtTokenService.parseId(token); int id = jwtTokenService.parseId(token);
List<SimpleGrantedAuthority> authorities = jwtTokenService.parseAuthorities(token); List<SimpleGrantedAuthority> authorities = jwtTokenService.parseAuthorities(token);
Authentication authToken = new UsernamePasswordAuthenticationToken(LoginMember.of(id,name), null, authorities);
Authentication authToken = new UsernamePasswordAuthenticationToken(
AuthMemberDto.of(id,name,authorities.getFirst().toString()),
null,
authorities
);
SecurityContextHolder.getContext().setAuthentication(authToken); SecurityContextHolder.getContext().setAuthentication(authToken);
} else { } else {
throw new JwtException("유효한 JWT 토큰이 없습니다."); throw new JwtException("유효한 JWT 토큰이 없습니다.");

View File

@ -1,6 +1,6 @@
package com.worlabel.global.resolver; package com.worlabel.global.resolver;
import com.worlabel.domain.auth.entity.dto.LoginMember; import com.worlabel.domain.auth.entity.dto.AuthMemberDto;
import com.worlabel.global.annotation.CurrentUser; import com.worlabel.global.annotation.CurrentUser;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
@ -14,6 +14,7 @@ import org.springframework.web.method.support.ModelAndViewContainer;
@Slf4j @Slf4j
@Component @Component
public class CurrentUserArgumentResolver implements HandlerMethodArgumentResolver { public class CurrentUserArgumentResolver implements HandlerMethodArgumentResolver {
@Override @Override
public boolean supportsParameter(MethodParameter parameter) { public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(CurrentUser.class); return parameter.hasParameterAnnotation(CurrentUser.class);
@ -22,8 +23,8 @@ public class CurrentUserArgumentResolver implements HandlerMethodArgumentResolve
@Override @Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if(principal instanceof LoginMember){ if(principal instanceof AuthMemberDto){
return ((LoginMember) principal).getId(); return ((AuthMemberDto) principal).getId();
} }
return null; return null;
} }