# 개요

이전 글에서 User Entity를 구현했고, 간단한 회원가입 API도 구현했다.

이번 글에서는 기존에 내가 알고 있던 로그인 API를 작성해보겠다.

선요약

  1. Login API 추가
    • LoginController 추가
    • UserService에 login() 추가

 

# Login API (Controller 이용)

프로젝트에서 먼저 회원가입을 API를 구현했고(이메일 중복체크, 닉네임 중복체크, 인증 코드 메일 API 등 회원가입에 부수적으로 필요한 API도 있었지만 이 글에서는 스킵했다.) 바로 로그인 API도 구현했다.

인증은 세션 방식과 토큰 방식이 있다는 것은 알고 있었지만 이 시점에서는 토큰 방식이 세션 방식보다 더 좋다는것도 몰랐고, 무엇보다도 구현하는 방법을 몰랐기 때문에 기존에 알고 있던 데로 세션에 방식으로 구현했다.

 

## Login API 구현

로그인을 위한 요구사항은 다음과 같았다.

  • 이메일과 비밀번호를 입력받는다.
  • 로그인에 성공하면 세션에 추가한다. → 이후에 세션, 토큰 방식의 차이를 알아보고 변경할 사항이 있다면 변경

이전 글과 마찬가지로 TDD 느낌을 내기 위해 API 테스트 후 구현하는 흐름으로 작성하겠다.

Login API 요청

코드를 작성하지 않았으니 당연히 실패한다. 위 요청 형식과 url에 맞게 Controller를 추가하고 그에 대한 비즈니스 로직을 Service 계층에 구현했다.

RestController 추가

UserController 하나로 회원가입과 로그인을 같은 클래스내에서 처리할 수 있었지만 SignUpController에 이메일,닉네임 중복체크, 인증코드 메일 전송, 인증코드 확인 API들이 있었기 때문에(이 프로젝트에는 생략했지만) LoginController를 추가했다.

더보기

LoginController.java 추가

package com.example.securityexample.user.controller;

// 생략...

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/login")
public class LoginController {

  @PostMapping("")
  public ResponseEntity<String> login(@RequestBody @Valid LoginDto loginDto) {
    
    return ResponseEntity.ok(Message.LOGIN_SUCCESS);
  }

}

Service 계층의 메서드 호출없이 응답으로 Status와 Message만 반환한다.

 

LoginDto.java 추가

package com.example.securityexample.user.dto;

// 생략...
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class LoginDto {

  @NotNull(message = Message.INVALID_EMAIL)
  @Pattern(regexp = Regexp.EMAIL, message = Message.INVALID_EMAIL)
  private String email;

  @NotNull(message = Message.NOT_MATCH_LOGIN_DTO)
  private String password;
}

 

Service 추가

더보기

UserService.java에 login() 메서드 추가

package com.example.securityexample.user.service;

// 생략...

@Service
@RequiredArgsConstructor
public class UserService {

  // 생략...

  public User login(LoginDto loginDto) {
    User user = userRepository.findByEmail(loginDto.getEmail())
        .orElseThrow(()-> new ResourceNotFoundException(Message.NOT_MATCH_LOGIN_DTO));

    if(passwordEncoder.matches(user.getPassword(), loginDto.getPassword())) {
      throw new ResourceNotFoundException(Message.NOT_MATCH_LOGIN_DTO);
    }

    return user;
  }
  
  // 생략...
}

 

LoginController에서 login() 호출

package com.example.securityexample.user.controller;

// 생략...
public class LoginController {

  private final UserService userService;

  @PostMapping("")
  public ResponseEntity<String> login(@RequestBody @Valid LoginDto loginDto, HttpSession session) {
    User loggedInUser = userService.login(loginDto);
    session.setAttribute("user", loggedInUser);

    return ResponseEntity.ok(Message.LOGIN_SUCCESS);
  }

}

세션에 User를 추가하는것으로 인증처리 했다.

 

API 테스트

성공

실패


 

# 결론

이번 글에서 추가한 내용은 다음과 같다.

  1. Login API 추가
    • LoginController 추가
    • UserService에 login() 추가

다음 글에서는 Spring Security 라이브러리 추가해보겠다.


 

# 전체 코드

 

GitHub - JinHoooooou/SecurityExample: Spring Security 적용기

Spring Security 적용기. Contribute to JinHoooooou/SecurityExample development by creating an account on GitHub.

github.com

 

+ Recent posts