본문 바로가기
개발

JWT 활용한 로그인 구현 - 3

by 공덕뉸나 2023. 9. 1.

이전 글에서 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