이전 글에서 JWT를 사용할 수 있게 코드를 다 짰었다.
그래서 이번에는 API를 만드는 과정을 정리해보고자 한다.
UserApi
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserApi {
private final UserService userService;
@PostMapping("/sign-in")
public ApiResult<SignInResponse> signIn(@Valid @RequestBody SignInRequest request) throws SignInException {
return success(userService.signIn(request));
}
}
나는 return 방식을 통일해주기 위해서 ApiResult 라는 것을 만들었는데 이것도 추후에 포스팅 해보도록 해야겠다.
@Valid
유효성 검사를 위한 어노테이션이다.
SignInRequest에 유효성 검사를 적용할 필드가 있어 사용했다.
SignInRequest
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SignInRequest {
@NotBlank
private String email;
@NotBlank
private String password;
private Boolean remember;
}
나는 로그인 할 때 이메일과 패스워드를 사용하기 때문에 @NotBlank를 걸었고, remember 값이 true이면 만료시간을 더 길게 적용하기 위해 remember 필드를 사용하였다.
UserService
public Users getUserByEmailAndPw(String email, String password)
throws SignInException {
Users user = getUserByEmail(email).orElseThrow(() ->
new SignInException(ResultCode.NOT_EXISTS,
String.format("%s(email: %s)", "Not Exists User.",
email)));
if (passwordEncoder.matches(password, user.getLoginPw())) {
return user;
}
throw new SignInException(ResultCode.NOT_EXISTS,
String.format("%s(email: %s, %s)", "Not Exists User.", email, password));
}
public SignInResponse signIn(SignInRequest request) throws SignInException {
Users user = this.getUserByEmailAndPw(request.getEmail(), request.getPassword());
SignInResponse signInResponse = user.signIn(request.getRemember());
return signInResponse;
}
우선 request로 넘어온 이메일과 패스워드로 존재하는 user인지 확인한 후 로그인을 한다.
Users -> signIn
public SignInResponse signIn(Boolean remember) {
String token = TokenService.generateToken(this, remember);
String refreshToken = TokenService.generateReFreshToken(this, remember);
Map<String, Object> claims = JwtUtil.getClaims(token);
LocalDateTime exp = LocalDateTime.ofInstant(
Instant.ofEpochSecond(Long.valueOf(claims.get("exp").toString())),
TimeZone.getDefault().toZoneId());
SignInResponse.Me me = SignInResponse.Me.builder()
.userEmail(userEmail)
.userId(userId)
.userName(userName)
.userPhoneNumber(EncryptService.decryptPhoneNumber(userPhoneNumber))
.nickName(nickName)
.build();
return SignInResponse.builder()
.userRoles(this.getUserRole())
.accessToken(token)
.refreshToken(refreshToken)
.expired(exp)
.me(me)
.build();
}
여기에서 토큰을 발급해서 return 한다.
SignInResponse에는 발급된 토큰, 만료시간, userRole, Me라는 사용자 정보가 들어있다.
SignInResponse
@Data
@Builder
public class SignInResponse {
private String accessToken;
private LocalDateTime expired;
private String refreshToken;
private List<UserRole> userRoles;
private Me me;
@Data
@Builder
@AllArgsConstructor
public static class Me {
private Long userId;
private String userEmail;
private String userName;
private String userPhoneNumber;
private String nickName;
}
}
이렇게 해서 swagger로 테스트해보면
이렇게 값을 던져준다.
로그인 구현하면서 생각할 것도 많고 조금 헤매기도 했는데 다시 코드 살펴보면서 익혀보도록 해야겠다. 망망!
'개발' 카테고리의 다른 글
Vue.js 사용하기 (0) | 2023.09.11 |
---|---|
Querydsl 세팅하기 (0) | 2023.09.06 |
JWT 활용한 로그인 구현 - 2 (0) | 2023.08.31 |
JWT 활용한 로그인 구현 - 1 (0) | 2023.08.30 |
Enum 생성 (1) | 2023.08.23 |