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 #26] JWT 관리(저장/재발급) 및 로그아웃 API #28

Merged
merged 42 commits into from
Aug 11, 2024
Merged
Changes from 1 commit
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
2fbef2f
[fix] : TokenService 삭제
dudxo Aug 9, 2024
d3ece77
[feat] : 소셜 로그인 성공 시 토큰 생성 로직 수정
dudxo Aug 9, 2024
c5baa49
[feat] : Token 관련 에러코드 추가
dudxo Aug 9, 2024
0fe6a83
[feat] : 남은 만료시간 반환 메서드 추가
dudxo Aug 9, 2024
db8ea1c
[feat] : 로그아웃 로직 추가
dudxo Aug 9, 2024
0526c5d
[feat] : DTO Valid 추가
dudxo Aug 9, 2024
b2bd960
[fix] : logout HttpMethod 변경 및 RequestBody 추가
dudxo Aug 9, 2024
8da544b
[feat] : accessToken logout 확인 로직 추가
dudxo Aug 9, 2024
23f5214
[feat] : 토큰 재발급 로직 추가
dudxo Aug 9, 2024
0de33c0
[refactor] : 변경감지를 이용한 ResponseDTO 생성
dudxo Aug 10, 2024
5f77c6e
[test] : Mocking을 이용한 Service 테스트 수정
dudxo Aug 10, 2024
840550e
[feat] : 로그아웃 실패 검증 로직 추가
dudxo Aug 10, 2024
4866b23
[feat] : 로그아웃 에러코드 추가
dudxo Aug 10, 2024
cfaa693
[fix] : 토큰 재발급 반환 타입 DTO 오류 수정
dudxo Aug 10, 2024
ccbccf3
[fix] : API '/' 누락 수정
dudxo Aug 10, 2024
f3f2c81
[feat] : 토큰 재발급 시 생성을 위한 인증 객체 추가
dudxo Aug 10, 2024
427ea4b
[fix] : MeberService.class <-> TokenProvider.class 순환참조 해결
dudxo Aug 10, 2024
21043a1
[test] : 로그아웃, 토큰 재발급 단위테스트 추가
dudxo Aug 10, 2024
128daa1
Merge branch 'dev' into feat/26/JWT-Logout
dudxo Aug 10, 2024
5c1942e
[fix] : @AuthenticationPrincipal를 통해 획득한 인증 객체 타입 변경
dudxo Aug 10, 2024
0ad361f
[test] : setUp시 refreshToken 생성 및 저장 추가
dudxo Aug 10, 2024
cb40730
[test] : MemberController 통합테스트 추가
dudxo Aug 10, 2024
4b6dfdc
[test] : 각 테스트 후 redis 초기화 추가
dudxo Aug 10, 2024
7e22abf
[feat] : 로그아웃/토큰 재발급 요청 DTO Valid Message 수정
dudxo Aug 11, 2024
ff4d80d
[feat] : 로그아웃 에러 코드 message 수정
dudxo Aug 11, 2024
129cd36
[feat] : 로그아웃 에러 코드 message 수정
dudxo Aug 11, 2024
8f77330
[style] : isOfficialEmailExists() 인라인 수정
dudxo Aug 11, 2024
3631a96
[refactor] : 메일 본문 내용 상수 선언을 통한 리팩토링
dudxo Aug 11, 2024
2123399
[fix] : MailService <-> MemberService 순환 참조 위험성 제거를 위한 변경
dudxo Aug 11, 2024
0d18502
[fix] : throw 누락 수정
dudxo Aug 11, 2024
7f0ff1a
[fix] : updateAdditionalInfo() 변경 감지에 의한 save() 로직 삭제
dudxo Aug 11, 2024
1da2ced
[style] : 반환 변수명 수정(findMember -> foundMember)
dudxo Aug 11, 2024
4fa5850
[refactor] : Enum 재사용성을 위한 parseProviderFromSocialEmail() 로직 리팩토링
dudxo Aug 11, 2024
4ea9fed
[test] : TokenProviderTest 추가
dudxo Aug 11, 2024
8d729a1
[rename] : isDuplicatedNickname() 닉네임 존재 여부 변수명 변경
dudxo Aug 11, 2024
0cc7d08
[test] : 실제 로직 변경으로 불필요해진 stub 제거
dudxo Aug 11, 2024
c69440b
[test] : 회원가입 API 통합 테스트를 위한 신규 회원 저장 로직 추가
dudxo Aug 11, 2024
cd5a73f
[test] : 실제 로직 변경으로 stub 변경 및 불필요한 mock 제거
dudxo Aug 11, 2024
1162d88
[test]: MemberFixture 객체 생성 메서드 추가
dudxo Aug 11, 2024
04b04e0
[refactor] : 소셜 이메일을 통한 Provider 찾는 로직 변경
dudxo Aug 11, 2024
930152d
[test] : parseProviderFromSocialEmail() 실제 로직 변경으로 인한 staticMock 추가
dudxo Aug 11, 2024
d40766d
[test] : Provider Test 작성
dudxo Aug 11, 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
Prev Previous commit
Next Next commit
[test] : TokenProviderTest 추가
dudxo committed Aug 11, 2024
commit 4ea9feddee591086fb998aa9a489bc5f0a702211
52 changes: 24 additions & 28 deletions src/test/java/com/dnd/gongmuin/security/jwt/TokenProviderTest.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
package com.dnd.gongmuin.security.jwt;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
import static org.mockito.MockitoAnnotations.*;
import static org.mockito.BDDMockito.*;

import java.util.Date;
import java.util.Optional;

import javax.crypto.SecretKey;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.transaction.annotation.Transactional;

import com.dnd.gongmuin.common.fixture.MemberFixture;
import com.dnd.gongmuin.member.domain.Member;
import com.dnd.gongmuin.member.repository.MemberRepository;
import com.dnd.gongmuin.redis.util.RedisUtil;
import com.dnd.gongmuin.security.jwt.util.TokenProvider;
import com.dnd.gongmuin.security.oauth2.AuthInfo;
import com.dnd.gongmuin.security.oauth2.CustomOauth2User;
@@ -29,29 +30,30 @@
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;

@Transactional
@ExtendWith(MockitoExtension.class)
@Disabled
class TokenProviderTest {

@Value("${spring.jwt.key}")
private String key;

@InjectMocks
private TokenProvider tokenProvider;

private SecretKey secretKey;
private AuthInfo authInfo;

@Mock
private AuthInfo authInfo;
private RedisUtil redisUtil;

@Mock
private MemberRepository memberRepository;

@InjectMocks
private TokenProvider tokenProvider;

@BeforeEach
void setUp() {
openMocks(this);

key = "oeq213n214eqf141n161saf145125t12tg2er31t3241g4v2r3131351332dsafsawefewqrft23fewfvdsafdsf32e1wq1r3ewfedfasdfsdafqrewqr1";
secretKey = Keys.hmacShaKeyFor(key.getBytes());

ReflectionTestUtils.setField(tokenProvider, "secretKey", secretKey);

this.authInfo = AuthInfo.of("김회원", "kakao123/daum.net");
}

@DisplayName("만료일이 30분인 토큰이 생성된다.")
@@ -61,18 +63,16 @@ void generateAccessToken() {
Date now = new Date();
long expectedExpirationTime = now.getTime() + 30 * 60 * 1000;

when(authInfo.getSocialEmail()).thenReturn("kakao123/kimMember@daum.net");
when(authInfo.getSocialName()).thenReturn("김회원");
CustomOauth2User authentication = new CustomOauth2User(authInfo);

// when
String accessToken = tokenProvider.generateAccessToken(authentication, now);
Claims claims = Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(accessToken).getPayload();

Date expiration = claims.getExpiration();

// then
assertThat(expiration.getTime()).isCloseTo(expectedExpirationTime, within(1000L));

}

@DisplayName("만료일이 1일인 토큰이 생성된다.")
@@ -82,14 +82,11 @@ void generateRefreshToken() {
Date now = new Date();
long expectedExpirationTime = now.getTime() + 1000 * 60 * 60 * 24;

when(authInfo.getSocialEmail()).thenReturn("kakao123/kimMember@daum.net");
when(authInfo.getSocialName()).thenReturn("김회원");
CustomOauth2User authentication = new CustomOauth2User(authInfo);

// when
String accessToken = tokenProvider.generateRefreshToken(authentication, now);
Claims claims = Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(accessToken).getPayload();

Date expiration = claims.getExpiration();

// then
@@ -102,18 +99,19 @@ void getAuthentication() {
// given
Date now = new Date();

when(authInfo.getSocialEmail()).thenReturn("kakao123/kimMember@daum.net");
when(authInfo.getSocialName()).thenReturn("김회원");
Member member = MemberFixture.member();
CustomOauth2User customOauth2User = new CustomOauth2User(authInfo);
String accessToken = tokenProvider.generateRefreshToken(customOauth2User, now);
String accessToken = tokenProvider.generateAccessToken(customOauth2User, now);

given(memberRepository.findBySocialEmail(anyString())).willReturn(Optional.ofNullable(member));

// when
Authentication authentication = tokenProvider.getAuthentication(accessToken);
CustomOauth2User getPrincipal = (CustomOauth2User)authentication.getPrincipal();
Member principal = (Member)authentication.getPrincipal();

// then
assertThat(authentication.isAuthenticated()).isTrue();
assertThat(getPrincipal.getEmail()).isEqualTo("kakao123/kimMember@daum.net");
assertThat(principal.getSocialEmail()).isEqualTo("KAKAO123/gongmuin@daum.net");
}

@DisplayName("토큰의 만료일이 현재 시간보다 전이면 만료된 토큰이다.")
@@ -122,8 +120,6 @@ void validateToken() {
// given
Date past = new Date(124, 6, 30, 16, 0, 0);

when(authInfo.getSocialEmail()).thenReturn("kakao123/kimMember@daum.net");
when(authInfo.getSocialName()).thenReturn("김회원");
CustomOauth2User customOauth2User = new CustomOauth2User(authInfo);
String accessToken = tokenProvider.generateRefreshToken(customOauth2User, past);