MemberController
@Slf4j
@Controller
@RequestMapping("/member")
@RequiredArgsConstructor
public class MemberController {
private final LoginValidator loginValidator;
private final LoginService loginService;
@GetMapping("/login")
public String login(@ModelAttribute RequestLogin form, @CookieValue(name="savedEmail", required = false) String savedEamil, @SessionAttribute(name="member", required = false) Member member) {
if(member != null) {
log.info(member.toString());
}
if(savedEamil != null){
form.setSaveEmail(true);
form.setEmail(savedEamil);
}
return "member/login";
}
@PostMapping("/login")
public String loginPs(@Valid RequestLogin form, Errors errors) {
loginValidator.validate(form, errors);
if (errors.hasErrors()) {
return "member/login";
}
loginService.process(form);
return "redirect:/";
}
@RequestMapping("/logout")
public String logout(HttpSession session){
session.invalidate(); //세션비우기
return "redirect:/member/login";
}
}
RequestLogin.java
@Data
public class RequestLogin {
@NotBlank
private String email;
@NotBlank
private String password;
private boolean saveEmail;
}
login.jsp
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<c:url var="actionUrl" value="/member/login" />
<spring:message var="saveEmailTitle" code='이메일_기억하기' />
<h1>
<spring:message code="로그인" />
</h1>
<form:form method="post" action="${actionUrl}" autocomplete="off" modelAttribute="requestLogin">
<dl>
<dt>
<spring:message code="이메일" />
</dt>
<dd>
<form:input path="email" />
<form:errors path="email" />
</dd>
</dl>
<dl>
<dt>
<spring:message code="비밀번호" />
</dt>
<dd>
<form:password path="password" />
<form:errors path="password" />
</dd>
</dl>
<div>
<form:checkbox path="saveEmail" value="true" label="${saveEmailTitle}" />
</div>
<form:errors element="div" delimiter="" />
<button type="submit">
<spring:message code="로그인" />
</button>
</form:form>
LoginValidator
@Component
@RequiredArgsConstructor
public class LoginValidator implements Validator {
private final MemberMapper mapper;
@Override
public boolean supports(Class<?> clazz) {
return clazz.isAssignableFrom(RequestLogin.class);
}
@Override
public void validate(Object target, Errors errors) {
//Bean Validation 검증 실패시에는 다음 검증을 진행 X
if (errors.hasErrors()) {
return;
}
/**
* 2) email로 회원이 조회 되는지 검증
* 3) 조회된 회원의 비밀번호가 입력한 값과 일치하는지 검증
*/
RequestLogin form = (RequestLogin)target;
String email = form.getEmail();
String password = form.getPassword(); // 사용자가 입력한 비밀번호
if (StringUtils.hasText(email)) {
Member member = mapper.get(email);
if (member == null) {
//errors.rejectValue("email", "Check.emailPassword");
errors.reject("Check.emailPassword");
}
if (member != null && StringUtils.hasText(password) && !BCrypt.checkpw(password, member.getPassword())) {
//errors.rejectValue("password", "Check.emailPassword");
errors.reject("Check.emailPassword");
}
}
}
}
LoginService
@Service
@RequiredArgsConstructor
public class LoginService {
private final MemberMapper mapper;
private final HttpSession session;
private final HttpServletResponse response;
public void process(String email) {
/**
* 1.email로 회원조회
* 2. 세션에 회원 정보 유지
*/
Member member = mapper.get(email);
if(email==null){
return;
}
session.setAttribute("member", member);
}
public void process(RequestLogin form) {
process(form.getEmail()); //로그인처리
/* 이메일 기억하기 처리 */
Cookie cookie = new Cookie("savedEmail", form.getEmail());
if(form.isSaveEmail()){ //쿠키등록
cookie.setMaxAge(60 * 60 * 24 * 7); //7일간 쿠키유지
}else{
cookie.setMaxAge(0); //쿠키제거
}
response.addCookie(cookie); //해당 쿠키가 삭제 or 등록
}
}