[게시판 프로젝트] Spring Security를 이용한 로그인(3)

J_Eddy·2021년 12월 7일
1

[게시판 프로젝트] Spring Security를 이용한 로그인(2) 게시물과 이어서 진행합니다

📌 로그인

회원가입까지 완료 하였다면 해당 아이디와 패스워드로 로그인 구현

html

<!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);
    }

이후 로그인 성공과 로그인 실패로 분기처리

로그인 성공

사용자가 어디서 로그인을 시도했을 지 모르므로 분기처리를 진행 하였다

  • 사용자가 권한이 없는 페이지로 접근 시도할 경우 강제 로그인이 시도 되는데 이렇게 인터셉트 당할 경우
    • 홈 화면으로 이동
  • 로그인 버튼을 눌러 접속했을 경우
    • 이전 페이지의 url을 저장한 후 로그인 완료 후 해당 url을 리턴

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);
    }

}

아이디가 존재하지 않을때

아이디 또는 패스워드가 틀릴 때

profile
논리적으로 사고하고 해결하는 것을 좋아하는 개발자입니다.

0개의 댓글