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

로그인 API response에 userId 필드 추가 #87

Merged
merged 4 commits into from
Sep 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 4 additions & 2 deletions src/main/java/com/cvsgo/controller/AuthController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.cvsgo.dto.SuccessResponse;
import com.cvsgo.dto.auth.LoginRequestDto;
import com.cvsgo.dto.auth.LoginResponseDto;
import com.cvsgo.dto.auth.LogoutRequestDto;
import com.cvsgo.dto.auth.TokenDto;
import com.cvsgo.service.AuthService;
Expand All @@ -23,7 +24,7 @@ public class AuthController {
private final AuthService authService;

@PostMapping("/login")
public SuccessResponse<TokenDto> login(@RequestBody LoginRequestDto request) {
public SuccessResponse<LoginResponseDto> login(@RequestBody LoginRequestDto request) {
return SuccessResponse.from(authService.login(request));
}

Expand All @@ -34,7 +35,8 @@ public SuccessResponse<Void> logout(@RequestBody LogoutRequestDto request) {
}

@GetMapping("/tokens")
public SuccessResponse<TokenDto> reissueToken(@RequestHeader("Authorization") String authorizationHeader) {
public SuccessResponse<TokenDto> reissueToken(
@RequestHeader("Authorization") String authorizationHeader) {
String refreshToken = authService.extractToken(authorizationHeader, TOKEN_TYPE);
return SuccessResponse.from(authService.reissueToken(refreshToken));
}
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/com/cvsgo/dto/auth/LoginResponseDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.cvsgo.dto.auth;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class LoginResponseDto {

private Long userId;

private TokenDto token;

@Builder
public LoginResponseDto(Long userId, TokenDto token) {
this.userId = userId;
this.token = token;
}
}
68 changes: 40 additions & 28 deletions src/main/java/com/cvsgo/service/AuthService.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import static com.cvsgo.util.AuthConstants.TOKEN_TYPE;

import com.cvsgo.dto.auth.LoginRequestDto;
import com.cvsgo.dto.auth.LoginResponseDto;
import com.cvsgo.dto.auth.TokenDto;
import com.cvsgo.entity.RefreshToken;
import com.cvsgo.entity.User;
Expand Down Expand Up @@ -38,7 +39,9 @@ public class AuthService {

private final RefreshTokenRepository refreshTokenRepository;

public AuthService(@Value("${jwt.secret-key}") final String secretKey, UserRepository userRepository, PasswordEncoder passwordEncoder, RefreshTokenRepository refreshTokenRepository) {
public AuthService(@Value("${jwt.secret-key}") final String secretKey,
UserRepository userRepository, PasswordEncoder passwordEncoder,
RefreshTokenRepository refreshTokenRepository) {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
this.refreshTokenRepository = refreshTokenRepository;
Expand All @@ -55,20 +58,26 @@ public AuthService(@Value("${jwt.secret-key}") final String secretKey, UserRepos
* @throws UnauthorizedException 비밀번호가 일치하지 않는 경우
*/
@Transactional
public TokenDto login(LoginRequestDto request) {
User user = userRepository.findByUserId(request.getEmail()).orElseThrow(() -> NOT_FOUND_USER);
public LoginResponseDto login(LoginRequestDto request) {
User user = userRepository.findByUserId(request.getEmail())
.orElseThrow(() -> NOT_FOUND_USER);
user.validatePassword(request.getPassword(), passwordEncoder);

String accessToken = createAccessToken(user, key, ACCESS_TOKEN_TTL_MILLISECOND);
RefreshToken refreshToken = RefreshToken.create(user, key, REFRESH_TOKEN_TTL_MILLISECOND);

TokenDto token = TokenDto.builder()
.accessToken(accessToken)
.refreshToken(refreshToken.getToken())
.tokenType(TOKEN_TYPE)
.build();

refreshTokenRepository.save(refreshToken);

return TokenDto.builder()
.accessToken(accessToken)
.refreshToken(refreshToken.getToken())
.tokenType(TOKEN_TYPE)
.build();
return LoginResponseDto.builder()
.userId(user.getId())
.token(token)
.build();
}

/**
Expand All @@ -79,7 +88,8 @@ public TokenDto login(LoginRequestDto request) {
*/
@Transactional
public void logout(String token) {
RefreshToken refreshToken = refreshTokenRepository.findByToken(token).orElseThrow(() -> UNAUTHORIZED_USER);
RefreshToken refreshToken = refreshTokenRepository.findByToken(token)
.orElseThrow(() -> UNAUTHORIZED_USER);
refreshTokenRepository.delete(refreshToken);
}

Expand All @@ -92,27 +102,29 @@ public void logout(String token) {
*/
@Transactional
public TokenDto reissueToken(String token) {
RefreshToken refreshToken = refreshTokenRepository.findByToken(token).orElseThrow(() -> UNAUTHORIZED_USER);
RefreshToken refreshToken = refreshTokenRepository.findByToken(token)
.orElseThrow(() -> UNAUTHORIZED_USER);
refreshToken.updateToken(key, REFRESH_TOKEN_TTL_MILLISECOND);
refreshTokenRepository.save(refreshToken);

String accessToken = createAccessToken(refreshToken.getUser(), key, ACCESS_TOKEN_TTL_MILLISECOND);
String accessToken = createAccessToken(refreshToken.getUser(), key,
ACCESS_TOKEN_TTL_MILLISECOND);

return TokenDto.builder()
.accessToken(accessToken)
.refreshToken(refreshToken.getToken())
.tokenType(TOKEN_TYPE)
.build();
.accessToken(accessToken)
.refreshToken(refreshToken.getToken())
.tokenType(TOKEN_TYPE)
.build();
}

private String createAccessToken(User user, Key key, long ttlMillis) {
long now = System.currentTimeMillis();
return Jwts.builder()
.setSubject(user.getUserId())
.setIssuedAt(new Date(now))
.setExpiration(new Date(now + ttlMillis))
.signWith(key)
.compact();
.setSubject(user.getUserId())
.setIssuedAt(new Date(now))
.setExpiration(new Date(now + ttlMillis))
.signWith(key)
.compact();
}

/**
Expand All @@ -139,9 +151,9 @@ public String extractToken(String authorizationHeaderValue, String tokenType) {
*/
public void validateToken(String token) {
Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token);
.setSigningKey(key)
.build()
.parseClaimsJws(token);
}

@Transactional(readOnly = true)
Expand All @@ -150,11 +162,11 @@ public Optional<User> getLoginUser(String accessToken) {
return Optional.empty();
}
String email = Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(accessToken)
.getBody()
.getSubject();
.setSigningKey(key)
.build()
.parseClaimsJws(accessToken)
.getBody()
.getSubject();
return userRepository.findByUserId(email);
}

Expand Down
26 changes: 16 additions & 10 deletions src/test/java/com/cvsgo/controller/AuthControllerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.cvsgo.argumentresolver.LoginUserArgumentResolver;
import com.cvsgo.config.WebConfig;
import com.cvsgo.dto.auth.LoginRequestDto;
import com.cvsgo.dto.auth.LoginResponseDto;
import com.cvsgo.dto.auth.LogoutRequestDto;
import com.cvsgo.dto.auth.TokenDto;
import com.cvsgo.exception.ExceptionConstants;
Expand Down Expand Up @@ -81,13 +82,17 @@ void respond_200_when_login_succeed() throws Exception {
.email("[email protected]")
.password("password1!")
.build();
TokenDto tokenDto = TokenDto.builder()
.accessToken(getSampleAccessToken())
.refreshToken(getSampleRefreshToken())
.tokenType(TOKEN_TYPE)
.build();

given(authService.login(any())).willReturn(tokenDto);
TokenDto token = TokenDto.builder()
.accessToken(getSampleAccessToken())
.refreshToken(getSampleRefreshToken())
.tokenType(TOKEN_TYPE)
.build();
LoginResponseDto loginResponseDto = LoginResponseDto.builder()
.userId(1L)
.token(token)
.build();

given(authService.login(any())).willReturn(loginResponseDto);

mockMvc.perform(post("/api/auth/login")
.contentType(MediaType.APPLICATION_JSON)
Expand All @@ -103,9 +108,10 @@ void respond_200_when_login_succeed() throws Exception {
),
responseFields(
fieldWithPath("timestamp").type(JsonFieldType.STRING).description("요청 시각"),
fieldWithPath("data.accessToken").type(JsonFieldType.STRING).description("액세스 토큰"),
fieldWithPath("data.refreshToken").type(JsonFieldType.STRING).description("리프레시 토큰"),
fieldWithPath("data.tokenType").type(JsonFieldType.STRING).description("토큰 종류")
fieldWithPath("data.userId").type(JsonFieldType.NUMBER).description("사용자 ID"),
fieldWithPath("data.token.accessToken").type(JsonFieldType.STRING).description("액세스 토큰"),
fieldWithPath("data.token.refreshToken").type(JsonFieldType.STRING).description("리프레시 토큰"),
fieldWithPath("data.token.tokenType").type(JsonFieldType.STRING).description("토큰 종류")
)
));
}
Expand Down
7 changes: 4 additions & 3 deletions src/test/java/com/cvsgo/service/AuthServiceTest.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.cvsgo.service;

import com.cvsgo.dto.auth.LoginRequestDto;
import com.cvsgo.dto.auth.LoginResponseDto;
import com.cvsgo.dto.auth.TokenDto;
import com.cvsgo.entity.RefreshToken;
import com.cvsgo.entity.User;
Expand Down Expand Up @@ -70,10 +71,10 @@ void should_get_tokens_when_succeed_to_login() {
given(userRepository.findByUserId(loginRequestDto.getEmail()))
.willReturn(Optional.of(user));

TokenDto tokenDto = authService.login(loginRequestDto);
LoginResponseDto loginResponseDto = authService.login(loginRequestDto);

assertNotNull(tokenDto.getAccessToken());
assertNotNull(tokenDto.getRefreshToken());
assertNotNull(loginResponseDto.getToken().getAccessToken());
assertNotNull(loginResponseDto.getToken().getRefreshToken());

}

Expand Down