Skip to content

Commit

Permalink
Merge pull request #285 from techeer-sv/BE/#284
Browse files Browse the repository at this point in the history
Be/#284 토큰 재발급 API 리팩토링
  • Loading branch information
youKeon authored Nov 7, 2023
2 parents 57317df + 414263e commit ba0a6b8
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
import com.graphy.backend.domain.auth.dto.request.LogoutRequest;
import com.graphy.backend.domain.auth.dto.response.GetTokenInfoResponse;
import com.graphy.backend.domain.auth.service.AuthService;
import com.graphy.backend.domain.auth.util.annotation.CurrentUser;
import com.graphy.backend.domain.member.domain.Member;
import com.graphy.backend.domain.member.dto.request.SignInMemberRequest;
import com.graphy.backend.domain.member.dto.request.SignUpMemberRequest;
import com.graphy.backend.global.result.ResultCode;
Expand Down Expand Up @@ -55,9 +53,8 @@ public ResponseEntity<ResultResponse> logout(@Validated @RequestBody LogoutReque

@Operation(summary = "reIssue", description = "토큰 재발급")
@PostMapping(value = "/reissue")
public ResponseEntity<ResultResponse> reissue(HttpServletRequest request,
@CurrentUser Member member) {
GetTokenInfoResponse response = authService.reissue(request, member);
public ResponseEntity<ResultResponse> reissue(HttpServletRequest request) {
GetTokenInfoResponse response = authService.reissue(request);
return ResponseEntity.ok(ResultResponse.of(ResultCode.AUTH_REISSUE_SUCCESS, response));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,9 @@ public Long getExpiration(String accessToken) {
Date expiration = Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(accessToken).getBody().getExpiration();
return (expiration.getTime() - System.currentTimeMillis());
}

public String getEmailInAuthentication(String AccessToken) {
Authentication authentication = this.getAuthentication(AccessToken);
return authentication.getName();
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.graphy.backend.domain.auth.service;

import com.graphy.backend.domain.auth.controller.JwtFilter;
import com.graphy.backend.domain.auth.domain.RefreshToken;
import com.graphy.backend.domain.auth.dto.request.LogoutRequest;
import com.graphy.backend.domain.auth.dto.response.GetTokenInfoResponse;
import com.graphy.backend.domain.auth.infra.TokenProvider;
import com.graphy.backend.domain.auth.repository.RefreshTokenRepository;
import com.graphy.backend.domain.member.domain.Member;
import com.graphy.backend.domain.member.dto.request.SignInMemberRequest;
import com.graphy.backend.domain.member.dto.request.SignUpMemberRequest;
import com.graphy.backend.domain.member.service.MemberService;
import com.graphy.backend.domain.auth.domain.RefreshToken;
import com.graphy.backend.domain.auth.repository.RefreshTokenRepository;
import com.graphy.backend.global.error.ErrorCode;
import com.graphy.backend.global.error.exception.InvalidTokenException;
import lombok.AccessLevel;
Expand All @@ -25,6 +25,7 @@


@Service
@Transactional
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
public class AuthService {
private final JwtFilter filter;
Expand All @@ -41,7 +42,6 @@ public void signUp(SignUpMemberRequest request) {
memberService.addMember(member);
}

@Transactional
public GetTokenInfoResponse signIn(SignInMemberRequest request) {

UsernamePasswordAuthenticationToken authenticationToken =
Expand All @@ -62,14 +62,13 @@ public GetTokenInfoResponse signIn(SignInMemberRequest request) {
return token;
}

@Transactional
public void logout(LogoutRequest request){
// 로그아웃 하고 싶은 토큰이 유효한 지 먼저 검증하기
if (!tokenProvider.validateToken(request.getAccessToken()))
throw new InvalidTokenException(ErrorCode.INPUT_INVALID_TOKEN);

// Access Token에서 User email을 가져온다
String email = tokenProvider.getAuthentication(request.getAccessToken()).getName();
String email = tokenProvider.getEmailInAuthentication(request.getAccessToken());

// Redis에서 해당 User email로 저장된 Refresh Token 조회
RefreshToken refreshToken = refreshTokenRepository.findByEmail(email);
Expand All @@ -89,28 +88,28 @@ public void logout(LogoutRequest request){
}


public GetTokenInfoResponse reissue(HttpServletRequest request, Member member) {
public GetTokenInfoResponse reissue(HttpServletRequest request) {
String requestToken = filter.resolveToken(request);
tokenProvider.validateToken(requestToken);

RefreshToken savedRefreshToken = refreshTokenRepository.findByEmail(member.getEmail());
String email = tokenProvider.getEmailInAuthentication(requestToken);

RefreshToken savedRefreshToken = refreshTokenRepository.findByEmail(email);
if (savedRefreshToken == null) throw new InvalidTokenException(ErrorCode.TOKEN_NOT_EXIST);

GetTokenInfoResponse newToken = tokenProvider.generateToken(savedRefreshToken.getToken(), savedRefreshToken.getAuthorities());
updateRefreshToken(member, savedRefreshToken, newToken);
updateRefreshToken(email, savedRefreshToken, newToken);

return newToken;
}


@Transactional
public void updateRefreshToken(Member member,
private void updateRefreshToken(String email,
RefreshToken savedRefreshToken,
GetTokenInfoResponse newToken) {

RefreshToken newRefreshToken = RefreshToken.builder()
.token(newToken.getRefreshToken())
.email(member.getEmail())
.email(email)
.authorities(savedRefreshToken.getAuthorities())
.build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
Expand Down Expand Up @@ -35,17 +34,22 @@ public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws
.cors().and()

.authorizeRequests()
.antMatchers("/api/v1/auth/signup",
"/api/v1/auth/signin",
"/api/v1/auth/logout",
"/api/v1/projects",
.antMatchers(
"/api/v1/auth/**",

"/api/v1/projects",
"/api/v1/projects/rank",
"/api/v1/projects/{projectId}",

"/api/v1/comments/{commentId}",

"/api/v1/recruitments",
"/api/v1/recruitments/{recruitmentId}",

"/api/v1/members/**",
"/swagger-ui/**").permitAll()
.antMatchers(HttpMethod.GET, "/api/v1/projects/{projectId}").permitAll()
.antMatchers(HttpMethod.GET, "/api/v1/comments/{commentId}").permitAll()

"/swagger-ui/**"
).permitAll()
.antMatchers("/api/v1/**").hasRole("USER")

.and()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.restdocs.payload.PayloadDocumentation.*;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
Expand Down Expand Up @@ -506,7 +505,7 @@ public void reIssueTest() throws Exception {
.build();

// when
when(authService.reissue(any(HttpServletRequest.class), any())).thenReturn(response);
when(authService.reissue(any(HttpServletRequest.class))).thenReturn(response);

// then
mvc.perform(post(BASE_URL + "/reissue")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,14 @@
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;

import javax.servlet.http.HttpServletRequest;


import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.mockito.BDDMockito.*;

@ExtendWith(MockitoExtension.class)
Expand Down Expand Up @@ -99,10 +96,9 @@ public void logoutTest() throws Exception {

// when
when(tokenProvider.validateToken(request.getAccessToken())).thenReturn(true);
when(tokenProvider.getAuthentication(request.getAccessToken())).thenReturn(authentication);
when(authentication.getName()).thenReturn(member.getEmail());
when(refreshTokenRepository.findByEmail(member.getEmail())).thenReturn(refreshToken);
when(tokenProvider.getExpiration(request.getAccessToken())).thenReturn(100000L);
when(tokenProvider.getEmailInAuthentication(request.getAccessToken())).thenReturn(member.getEmail());

// then
assertDoesNotThrow(() -> authService.logout(request));
Expand Down Expand Up @@ -149,8 +145,9 @@ public void reissueTest() throws Exception {
when(tokenProvider.validateToken(requestToken)).thenReturn(true);
when(refreshTokenRepository.findByEmail(member.getEmail())).thenReturn(savedRefreshToken);
when(tokenProvider.generateToken(savedRefreshToken.getToken(), savedRefreshToken.getAuthorities())).thenReturn(newToken);
when(tokenProvider.getEmailInAuthentication(requestToken)).thenReturn(member.getEmail());

GetTokenInfoResponse actual = authService.reissue(request, member);
GetTokenInfoResponse actual = authService.reissue(request);

// then
assertThat(actual).usingRecursiveComparison().isEqualTo(newToken);
Expand All @@ -166,12 +163,10 @@ public void reissueNotExistRefreshTokenExceptionTest() throws Exception {
// when
when(filter.resolveToken(any(HttpServletRequest.class))).thenReturn(requestToken);
when(tokenProvider.validateToken(requestToken)).thenReturn(true);
when(refreshTokenRepository.findByEmail(member.getEmail())).thenReturn(null);


// then
assertThatThrownBy(
() -> authService.reissue(request, member))
() -> authService.reissue(request))
.isInstanceOf(InvalidTokenException.class)
.hasMessageContaining("존재하지 않는 토큰");
}
Expand Down

0 comments on commit ba0a6b8

Please sign in to comment.