로그인은 Email과 password를 받아와 검증 후, JWT Access Token을 발행하는 로직으로 진행한다.
1. LoginRequestDto, LoginResponseDto 작성
@Data
public class LoginRequestDto {
@NotBlank(message = "빈 항목이 존재합니다.")
@Email(message = "이메일 양식이 올바르지 않습니다.")
private String email;
@NotBlank(message = "빈 항목이 존재합니다.")
private String password;
@Builder
public LoginRequestDto(String email, String password) {
this.email = email;
this.password = password;
}
}
@Data
public class LoginResponseDto {
private String accessToken;
@Builder
public LoginResponseDto(String accessToken) {
this.accessToken = accessToken;
}
}
- LoginRequestDto 는 JSR-303 검증을 통해 이메일 형식인지, Blank인지를 검증한다.
- 검증 성공 시, key값이 accessToken으로 JWT 토큰을 담아 응답한다.
2. JwtTokenProvider 생성
implementation 'io.jsonwebtoken:jjwt:0.9.1'
- jsonwebtoken 라이브러리를 사용하여 JWT 토큰을 생성한다.
jwt:
secret: {사용자 지정 Secret Key}
access-token-expire-time: 18000000000
- application.yml에 서명을 위한 secret 키와 토큰 만료시간을 설정해준다.
@Component
public class JwtTokenProvider {
@Value("${jwt.access-token-expire-time}")
private Long expireTime;
@Value("${jwt.secret}")
private String secretKey;
public String createJwt(String email) {
Claims claims = Jwts.claims();
claims.put("email", email);
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + expireTime))
.signWith(SignatureAlgorithm.HS256, secretKey)
.compact();
}
}
- Jwt 토큰에 사용자 email을 클레임으로 삽입 및 생성시간/만료시간 설정 후 서버에 지정한 secretKey를 통해 HS256 알고리즘으로 암호화 한다.
3. UserService login 구현
@Transactional
public String login(LoginRequestDto requestDto) throws Exception {
String email = requestDto.getEmail();
String password = requestDto.getPassword();
User savedUser = userRepository.findByEmail(email).orElseThrow(() -> new UsernameNotFoundException("로그인 정보가 잘못되었습니다."));
if(passwordEncoder.matches(password, savedUser.getPassword())) {
String token = jwtTokenProvider.createJwt(email);
log.info("User [{}] token published -> {}", email, token);
return token;
}
else {
throw new Exception("로그인 정보가 잘못되었습니다.");
}
}
- 입력받은 email을 통하여 DB에서 해당 유저를 찾아 savedUser에 저장한다.
- passwordEncoder의 matches 메서드를 통하여 입력받은 비밀번호와 DB에 저장된 비밀번호가 같은지 검사하고, 일치한다면 Jwt 토큰을 발행하며 그렇지 않다면 예외를 발생시킨다.
4. UserController login 구현
@PostMapping("/login")
public ResponseEntity login(@Valid @RequestBody LoginRequestDto requestDto, BindingResult bindingResult) {
if(bindingResult.hasErrors()) {
String errorMsg = bindingResult.getFieldError().getDefaultMessage();
return ResponseEntity.badRequest().body(errorMsg);
}
try {
String accessToken = userService.login(requestDto);
return ResponseEntity.ok().body(LoginResponseDto.builder().accessToken(accessToken).build());
} catch (Exception e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
}
- JSR-303 검증을 통해 입력 형식에 오류가 있다면 오류메시지와 함께 400 에러를 발생시킨다.
- userService의 로그인 로직을 정상적으로 수행하면, LoginResponseDto에 accessToken을 담아 응답하고, 그렇지 않다면 오류메시지와 함께 400에러를 응답한다.
'Web > 인스타 클론 코딩' 카테고리의 다른 글
[인스타그램 클론코딩] 04. JWT 필터 구현(Back-End) (0) | 2023.02.01 |
---|---|
[인스타그램 클론코딩] 03. 로그인 구현(Front-End) (0) | 2023.02.01 |
[인스타그램 클론코딩] 02. 회원 가입 구현(Front-End) (0) | 2023.01.31 |
[인스타그램 클론코딩] 02. 회원 가입 구현(Back-End) (0) | 2023.01.31 |
[인스타그램 클론코딩] 01. 기술 스택 정하기 (0) | 2023.01.31 |