본문 바로가기
스프링과 JPA 기반 웹 어플리케이션 개발/1부 (개발환경, 회원가입, 로그인, 계정설정)

17. 로그인 / 로그아웃

by Backchus 2020. 4. 20.

커스텀 로그인 페이지 만들기

로그인 화면

스프링 시큐리티 로그인/로그아웃 설정

http.formLogin()
	.loginPage("/login").permitAll();
    
http.logout()
	.logoutSuccessUrl("/");

 

스프링 시큐리티 로그인 기본 값

  • username
  • password
  • POST "/login"

SecurityConfig에서 로그인 로그아웃 처리 추가

package me.weekbelt.studyolle.config;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        
        // 기존 코드 .........

        http.formLogin()                     // 로그인 페이지(기본 값값)
                .loginPage("/login")         // 커스텀한 로그인 페이지
                .permitAll();                // 접근 권한(모두 가능)

        http.logout()
                .logoutSuccessUrl("/")       // 로그아웃 성공시 메인페이지 이동
        ;
    }

    // 기존 코드 ......
}

 

MainController에 login요청을 실행할 핸들러 추가

package me.weekbelt.studyolle.main;

@Controller
public class MainController {

    // 기존 코드 .....

    @GetMapping("/login")
    public String login(){
        return "login";
    }
}

 

fragments.html에 javascript로직 추가

<!DOCTYPE html>
<html lang="en"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/extras/spring-security">

// 기존 코드 .........

<script type="application/javascript" th:fragment="form-validation">
    (function () {
        'use strict';

        window.addEventListener('load', function () {
            // Fetch all the forms we want to apply custom Bootstrap validation styles to
            const forms = document.getElementsByClassName('needs-validation');

            // Loop over them and prevent submission
            Array.prototype.filter.call(forms, function (form) {
                form.addEventListener('submit', function (event) {
                    if (form.checkValidity() === false) {
                        event.preventDefault();
                        event.stopPropagation();
                    }
                    form.classList.add('was-validated')
                }, false)
            })
        }, false)
    }())
</script>
</html>

 

sign-up.html에 기존 script로직 삭제 후

<script th:replace="fragments.html :: form-validation"></script>

추가

 

/login.html 작성

<!DOCTYPE html>
<html lang="en"
      xmlns:th="http://www.thymeleaf.org">
<!--head-->
<head th:replace="fragments.html::head"></head>

<body class="bg-light">
<!--네비게이션 바-->
<div th:replace="fragments.html::main-nav"></div>


<div class="container">
    <div class="py-5 text-center">
        <p class="lead">스터디올래</p>
        <h2>로그인</h2>
    </div>
    <div class="row justify-content-center">
        <div th:if="${param.error}" class="alert alert-danger" role="alert">
            <p>이메일(또는 닉네임)과 패스워드가 정확하지 않습니다.</p>
            <p>또는 확인 되지 않은 이메일을 사용했습니다. 이메일을 확인해 주세요.</p>
            <p>
                확인 후 다시 입력하시거나, <a href="#" th:href="@{/find-password}">패스워드 찾기</a>를 이용하세요.
            </p>
        </div>

        <form class="needs-validation col-sm-6" action="#" th:action="@{/login}" method="post" novalidate>
            <div class="form-group">
                <label for="username">이메일 또는 닉네임</label>
                <input id="username" type="text" name="username" class="form-control"
                       placeholder="your@email.com" aria-describedby="emailHelp" required>
                <small id="emailHelp" class="form-text text-muted">
                    가입할 때 사용한 이메일 또는 닉네임을 입력하세요.
                </small>
                <small class="invalid-feedback">이메일을 입력하세요.</small>
            </div>
            <div class="form-group">
                <label for="password">패스워드</label>
                <input id="password" type="password" name="password" class="form-control"
                       aria-describedby="passwordHelp" required>
                <small id="passwordHelp" class="form-text text-muted">
                    패스워드가 기억나지 않는다면, <a href="#" th:href="@{/emaillogin}">패스워드 없이 로그인하기</a>
                </small>
                <small class="invalid-feedback">패스워드를 입력하세요.</small>
            </div>

            <div class="form-group">
                <button class="btn btn-success btn-block" type="submit"
                aria-describedby="submitHelp">로그인</button>
                <small id="submitHelp" class="form-text text-muted">
                    스터디올래에 처음 오신거라면 <a href="#" th:href="@{/signup}">계정을 먼저 만드세요.</a>
                </small>
            </div>
        </form>
    </div>
    <!-- footer -->
    <div th:replace="fragments.html::footer"></div>
</div>
<script th:replace="fragments.html :: form-validation"></script>
</body>
</html>

form태그에서 action="@{/login}"에서 post요청은 위에서 스프링시큐리티 설정으로 인해 자동으로 처리해주기 때문에

Controller에서 따로 post 처리하기 위한 핸들러를 만들어줄 필요가 없다. 하지만 로그인을 처리하기 위해 DB에서 계정 정보를 가져와야 하므로 AccountService에서 UserDetailService인터페이스를 상속받아 loadUserByUsername메소드를 구현해야한다.

package me.weekbelt.studyolle.account;

@RequiredArgsConstructor
@Service
public class AccountService implements UserDetailsService {    // UserDetailService인터페이스를 상속

    // 기존 코드

    @Override
    public UserDetails loadUserByUsername(String emailOrNickname) throws UsernameNotFoundException {
        Account account = accountRepository.findByEmail(emailOrNickname);
        if(account == null) {
            account = accountRepository.findByNickname(emailOrNickname);
        }

        if (account == null) {
            throw new UsernameNotFoundException(emailOrNickname);
        }

        return new UserAccount(account);
    }
}

 

AccountRepository에 findByNickname메소드 추가

package me.weekbelt.studyolle.account;

@Transactional(readOnly = true)
public interface AccountRepository extends JpaRepository<Account, Long> {

    // 기존 코드 ....

    Account findByNickname(String nickname);
}

 

 

참고: https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-JPA-%EC%9B%B9%EC%95%B1#

 

스프링과 JPA 기반 웹 애플리케이션 개발 - 인프런

이 강좌에서 여러분은 실제로 운영 중인 서비스를 스프링, JPA 그리고 타임리프를 비롯한 여러 자바 기반의 여러 오픈 소스 기술을 사용하여 웹 애플리케이션을 개발하는 과정을 학습할 수 있습니다. 이 강좌를 충분히 학습한다면 여러분 만의 웹 서비스를 만들거나 취직에 도움이 될만한 포트폴리오를 만들 수 있을 겁니다. 활용 웹 개발 프레임워크 및 라이브러리 Java Spring Spring Boot Spring Data JPA Thymeleaf 온라인 강의 스

www.inflearn.com