[게시판 프로젝트] Spring Security를 이용한 로그인(2) 게시물과 이어서 진행합니다
회원가입까지 완료 하였다면 해당 아이디와 패스워드로 로그인 구현
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
...
</head>
<body class="text-center">
<form class="form-signin" th:action="@{/account/login}" method="post">
<a th:href="@{/}">로고</a>
<h1 class="h3 mb-3 fw-normal">로그인</h1>
<!--로그인에러-->
<div th:if="${param.error}" th:text="${loginFailMsg}" class="alert alert-danger" role="alert"></div>
<!--로그아웃-->
<div th:if="${param.logout}" class="alert alert-primary" role="alert">
로그아웃 되었습니다.
</div>
<div class="mb-3">
<label for="username"></label>
<input type="eamil" class="form-control" id="username" name="username" placeholder="Email">
</div>
<div class="mb-3">
<label for="password"></label>
<input type="password" class="form-control" id="password" name="password" placeholder="Password">
</div>
<div class="mb-3">
<button class="w-100 btn btn-lg btn-primary " type="submit">로그인</button>
</div>
<!--<div class="mb-3">
<a id="kakao_login" type="submit" th:href="@{/kakao/oauth}"><img src="/images/kakao_login_medium_wide.png"></a>
</div>-->
<div class="mb-3">
<p>아직 회원이 아니신가요?</p>
<a type="button" class="w-100 btn btn-lg btn-outline-primary" th:href="@{/account/register}">회원가입</a>
</div>
</form>
</body>
</html>
Member Service
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Optional<MemberEntity> memberEntityWrapper = memberRepository.findByUsername(username);
MemberEntity memberEntity = memberEntityWrapper.get();
List<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority(memberEntity.getRole().getValue()));
return new User(memberEntity.getUsername(), memberEntity.getPassword(), authorities);
}
이후 로그인 성공과 로그인 실패로 분기처리
사용자가 어디서 로그인을 시도했을 지 모르므로 분기처리를 진행 하였다
MemberLoginSuccessService
@Service
public class MemberLoginSuccessService implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
/*강제 인터셉트 당했을 경우의 데이터 get*/
RequestCache requestCache = new HttpSessionRequestCache();
SavedRequest savedRequest = requestCache.getRequest(request, response);
/*로그인 버튼 눌러 접속했을 경우의 데이터 get*/
String prevPage = (String) request.getSession().getAttribute("prevPage");
//url 기본 값
String url = "/";
/*이전 페이지가 접근 제한 페이지일 경우*/
if (savedRequest != null) {
url = savedRequest.getRedirectUrl();
/*로그인 버튼 눌러서 접근한 경우*/
} else if (prevPage != null) {
url = prevPage;
}
/*로그인 완료시 세션저장*/
MemberDto memberDto = memberService.memberInfo(authentication.getName());
HttpSession session = request.getSession(false);
session.setAttribute("memberId", memberDto.getId());
session.setAttribute("memberUsername", memberDto.getUsername());
session.setAttribute("memberNickname", memberDto.getNickname());
session.setAttribute("memberGender", memberDto.getGender());
session.setAttribute("memberAge", memberDto.toEntity().getAge());
session.setAttribute("memberRole", memberDto.getRole());
response.sendRedirect(url);
}
}
에러메세지를 설정
이후 해당 메세지를 담에 view에 전송
MemberLoginFailService
@Service
public class MemberLoginFailService implements AuthenticationFailureHandler {
private final String DEFAULT_FAILURE_URL = "/account/login?error=true";
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
String loginFailMsg = null;
if (exception instanceof AuthenticationServiceException) {
loginFailMsg = "존재하지 않는 사용자입니다.";
} else if(exception instanceof BadCredentialsException) {
loginFailMsg = "아이디 또는 비밀번호가 틀립니다.";
}
request.setAttribute("loginFailMsg", loginFailMsg);
request.getRequestDispatcher(DEFAULT_FAILURE_URL).forward(request,response);
}
}
아이디가 존재하지 않을때
아이디 또는 패스워드가 틀릴 때