이제 찜 기능과 게시판 기능을 만들기 위해서 로그인정보를 구현해야 할 때가 되었다. 로그인은 Spring Security
을 사용할건데 로그인과정의 자세한 내용은 여기와 여기에 포스팅해두었다 😀
SecurityfilterChain
과 UserDetailsService
를 활용하여 구현해보았다. 대략적인 과정은
@EnableWebSecurity
@Configuration
public class WebSecurityConfig {
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorizeRequests ->
authorizeRequests
.requestMatchers("/members/login", "/").permitAll()
// .anyRequest().authenticated()
)
.csrf(AbstractHttpConfigurer::disable)
.formLogin(formLogin ->
formLogin
.loginPage("/members/login")
.usernameParameter("username")
.passwordParameter("password")
.defaultSuccessUrl("/", true)
)
.logout((logout)-> logout
.logoutRequestMatcher(new AntPathRequestMatcher("/members/logout"))
.logoutSuccessUrl("/")
.invalidateHttpSession(true)
)
;
return http.build();
}
}
권한설정은 테스트니까 authenticated는 빼두고 진행했다. 로그인, 로그아웃 경로를 설정하고 PasswordEncoder
빈을 등록
private final PasswordEncoder passwordEncoder;
@Override
public void join(MemberDTO memberDTO) {
...
Member member = Member.builder()
.username(memberDTO.getUsername())
//비밀번호 암호화 완료
.password(passwordEncoder.encode(memberDTO.getPassword()))
.nickname(memberDTO.getNickname())
.email(memberDTO.getEmail())
.gender(memberDTO.getGender())
.role(role)
.build();
...
}
passwordEncoder
으로 비밀번호 로직 수정
@RequiredArgsConstructor
@Service
public class MemberSecurityServiceImpl implements UserDetailsService {
private final MemberRepository memberRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Member member = memberRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("사용자를 찾을 수 없습니다."));
List<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority(member.getRole().equals(ADMIN) ? "ADMIN" : "USER"));
return new User(member.getUsername(), member.getPassword(), authorities);
}
}
loadUserByUsername을 커스텀해서 User 객체로 반환
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>로그인 폼</title>
</head>
<body>
<h2>Login</h2>
<form action="/members/login" method="post">
<div>
<label for="username">Username:</label>
<input type="text" id="username" name="username" required>
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
</div>
<div>
<button type="submit">Login</button>
</div>
</form>
</body>
</html>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home</title>
</head>
<body>
<h2>홈</h2>
<a th:href="@{/members/signup}">회원 가입</a>
<a sec:authorize="isAnonymous()" th:href="@{/members/login}" >로그인</a>
<a sec:authorize="isAuthenticated()" th:href="@{/members/logout}" >로그아웃</a>
<a th:href="@{/product/upload}">상품 등록</a>
<a th:href="@{/product/list}">상품 리스트</a>
</body>
</html>
로그인과 로그아웃을 알아보기위해 isAnonymous
와 isAuthenticated
을 사용
임시 home 폼
admin으로 로그인
로그인이 인증되어 로그아웃버튼이 보이는 모습