@Service
@RequiredArgsConstructor
public class LoginService {
private final MemberRepository memberRepository;
public Member login(String loginId, String password){
return memberRepository.findByLoginId(loginId)
.filter( m -> m.getPassword().equals(password))
.orElse(null);
}
}
도메인을 먼저 만들었다.
먼저 만든 findByLogin해서 나온 걸 확인하는 거다.
저거 정의할 때 return을 Optional로 하게 해서, Optional 함수 filter를 쓸 수 있다.
filter()는 stream()같은 콜렉션 형태로 반환되는거에도 쓸 수 있고, 단일 Optional 객체에도 쓸 수 있다.
여튼 findByLoginId() 해서 나온 걸 filter로 m이라는 별칭으로 그 m이 가지고 있는 password랑 인자로 받은 password와 같은 지 검사한다. 만약 같으면 저 m을 return 하는거고, 아니면 orElse(null)해서 null을 반환하는거다.
@Data
public class LoginForm {
@NotEmpty
private String loginId;
@NotEmpty
private String password;
}
로그인용 클래스를 따로 만들었다.
@Slf4j
@Controller
@RequiredArgsConstructor
public class LoginContoller {
private final LoginService loginService;
@GetMapping("/login")
public String loginForm(@ModelAttribute LoginForm form){
return "login/loginForm";
}
@PostMapping("/login")
public String login(@Validated @ModelAttribute LoginForm loginForm, BindingResult bindingResult){
if(bindingResult.hasErrors()){
return "login/loginForm";
}
Member loginMember = loginService.login(loginForm.getLoginId(), loginForm.getPassword());
if(loginMember == null){
bindingResult.reject("loginFail", "아이디 혹은 비밀번호가 맞지 않습니다.");
return "/login/loginForm";
}
return "redirect:/";
}
}
loginForm()은 패스,
login()은
검증 해 보고 에러가 나오면 다시 login/loginForm으로 이동시킨다. 이 때 url로 준게 아니고 템플릿 주소라서 그냥 템플릿에 설정해 놓은 타임리프 에러 로직에 따라 동작한다.
물론 새로고침하면 본래 Post 요청으로 보냈던 거라, 다시 잘못된 비밀번호 혹은 아이디를 가지고 다시 요청을 보내는 거다.
여튼
도메인의 loginService의 login() 로직을 수행해 본다. 만약 null이라면 bindingResult에 reject()로 오브젝트 에러를 추가해 주고 다시 로그인폼 템플릿으로 보낸다.
만약 null도 아니라면 redirection으로 홈으로 이동시킨다.
새로고침으로 연속되는 로그인 요청 및 성공을 막기 위해.
Post는 대부분 PRG를 고려 해야 한다.
'스프링 > 4. 스프링 MVC-2' 카테고리의 다른 글
47. 쿠키의 보안문제 (0) | 2023.09.05 |
---|---|
46. 쿠키를 이용한 로그인 구현. (0) | 2023.09.05 |
44. 멤버 회원가입 구현 (0) | 2023.09.04 |
43. 도메인과 표현 분리 (0) | 2023.09.04 |
42. Http 메시지(Rest API) 검증 (0) | 2023.09.04 |