18. 로그인 로그아웃
커스텀 로그인 페이지 만들기
> 로그인 유지 체크
> id : 이메일/닉네임 , pw
> 회원가입 링크
스프링 시큐리티 로그인/로그아웃 설정
> http.formLogin().loginPage("/login").permitAll();
> http.logout().logoutSuccessUrl("/");
스프링 시큐리티 로그인 기본값
> username
> password
> POST "/login"
Spring security 로그인/ 로그아웃 설정
SecurityConfig.java
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.mvcMatchers("/", "/login","/sign", "/sign-up", "/check-email-token",
"/email-login", "/check-email-login", "/login-link").permitAll()
.mvcMatchers(HttpMethod.GET, "/profile/*").permitAll()
.anyRequest().authenticated();
http.formLogin()
.loginPage("/login").permitAll();
http.logout()
.logoutSuccessUrl("/");
}
configure 설정 완료 후 이를 처리할 핸들러를 만들어보자
Maincontroller.java
@GetMapping("/login")
public String login(){
return "login";
}
templates/login.html로 이동 (viewController로 코드를 줄일 수 있지만 나중에 적용)
로그인 뷰 만들기
login.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace ="fragments.html :: head"></head>
<body class="bg-light">
<nav th:replace="fragments.html :: main-nav"></nav>
<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>
<!-- POST :/login의 기능은 따로 controller설정 안하여도 security에서 제공-->
<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="@{/email-login}">패스워드 없이 로그인하기</a>
</small>
<small class="invalid-feedback">패스워드를 입력하세요.</small>
</div>
<!-- submit-->
<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 th:replace="fragments.html :: footer"></footer>
</div>
<script th:replace="fragments.html :: form-validation"></script>
</body>
</html>
form login을 처리하는 post 메소드는 Spring Security가 지원해준다 ( ID, PW값을 받고 제출 -> user ? yes : no)
로그인이 완료되기 위해서는 id / pw을 입력 후 로그인 버튼을 눌렀을 때 DB에 있는 user data를 조회하여 매칭이 되는지 확인해야 하는데 그러려면 security에 있는 UserDetailsService를 사용하여야 한다.
@Service
@RequiredArgsConstructor
public class AccountService implements UserDetailsService {
/**
* DB에 있는 user정보 조회
*/
@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);
}
//User Principal 반환
return new UserAccount(account);
}
]
결과화면
- 로그아웃하면 "/" 기본화면으로 이동
1. 로그인 뷰
2. 잘못 입력시 에러메시지 노출
3. 로그인 성공 화면 -> "/index"로 이동
+ 로그인할 때 입력한 현재 비밀번호 값은 plain text로 들어온다
@Bean
public PasswordEncoder passwordEncoder(){
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
원래는 AuthenticationManager에다 userDetails와 PasswordEncoder를 아래와 같이 설정해주어야 한다.
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception{
authenticationManagerBuilder
.userDetailsService(userService)
.passwordEncoder(passwordEncoder());
}
그런데 Springboot기본 설정을 따른다면 PasswordEncoder나 UserDetailsService는 Bean으로 등록이 되어있으면 spring에서 알아서 픽업해가니 따로 명시적으로 설정은 하지 않아도 된다.
(만약 PasswordEncoder나 UserDetailsService가 여러 개다? 그러면 다른 방법으로 풀어나가야 한다.)
> UserDetailsService가 여러개면 위와 같이 해당 service와 passwordencode를 같이 authenticationManager에 넣어주는 방식으로 하는 것 같다
(뇌피셜)
참고
'Dot Programming > Spring Clone' 카테고리의 다른 글
[스프링 웹앱 프로젝트 #20] 로그인 기억하기 (0) | 2020.12.10 |
---|---|
[스프링 웹앱 프로젝트 #19] 로그인 / 로그아웃 테스트 (0) | 2020.12.09 |
[스프링 웹앱 프로젝트 #17] 가입 확인 이메일 재전송 (0) | 2020.12.08 |
[스프링 웹앱 프로젝트 #16] 현재 인증된 사용자 정보 참조 (0) | 2020.12.07 |
[스프링 웹앱 프로젝트 #15] 첫 페이지 보완 (Fontawesome, Jdenticon 사용) (0) | 2020.12.01 |