
AppConfiguration(๋ก๊ทธ์ธ์ ํ์ํ ์ค์ )
@Configuration
@EnableMethodSecurity
public class AppConfiguration {
//๋ก๊ทธ์ธ ํ์ด์ง ๋ด๊ฐ ์์ฑํ๋๋ก ์คํ๋ง ๊ธฐ๋ณธ ๋ก๊ทธ์ธ ํ์ด์ง๊ฐ ์๋
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf(csrf -> csrf.disable());
http.formLogin(login -> login.loginPage("/member/login"));
return http.build();
}
// ์ํธํ
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
์คํ๋ง ์ํ๋ฆฌํฐ๋ฅผ ์ฌ์ฉํ์ฌ ๋ก๊ทธ์ธ์ ํ๊ธฐ ์ํ URL์ ์ค์ ํฉ๋๋ค.
.formLogin ๋ฉ์๋๋ ์คํ๋ง ์ํ๋ฆฌํฐ์ ๋ก๊ทธ์ธ ๋ด๋นํ๋ ๋ถ๋ถ์ผ๋ก ๋ก๊ทธ์ธ ํ์ด์ง์ URL์ /member/login์ผ๋ก ์ค์ ํฉ๋๋ค.
BCryptPasswordEncoder : ์ํธํํ๊ธฐ ์ํด ์ธ์ฝ๋ฉํ๋ ์ฝ๋์
๋๋ค.
CustomUserDetailsService(์ฌ์ฉ์์ ์ ๋ณด๋ฅผ ๋ก๋)
@Component
@RequiredArgsConstructor
public class CustomUserDetailsService implements UserDetailsService {
private final MemberMapper mapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return new CustomUser(mapper.selectByEmail(username));
}
}
form์์ ๋ฐ๋ email, password๋ ์ํ๋ฆฌํฐ(userDetails)์์ ๋ฐ๋ username, password๋ ๊ฐ์์ผ ๋ก๊ทธ์ธ์ ํ ์ ์์ต๋๋ค.UserDetailsService์ ์ถ์ ๋ฉ์๋์ธ loadUserByUsername๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉํฉ๋๋ค.loadUserByUsername์์ ์ฌ์ฉ์๊ฐ ์ ๊ณตํ ์ด๋ฉ์ผ์ ๋ฐ์์ ํด๋น ์ด๋ฉ์ผ์ ๊ธฐ๋ฐ์ผ๋ก ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋ ์ญํ ์ ํฉ๋๋ค. ์ฌ๊ธฐ์๋ MemberMapper๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฉ์ผ์ ํด๋นํ๋ ํ์ ์ ๋ณด๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์กฐํํฉ๋๋ค.loadUserByUsername ๋ฉ์๋์์ ๋ฐํ๋ ์ ๋ณด์ ๋น๊ตํ์ฌ ์ธ์ฆํฉ๋๋ค.CustomUser ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค. CustomUser๋ UserDetails ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ์ฌ์ฉ์ ์ ๋ณด ๊ฐ์ฒด์ด๋ฉฐ ์ฌ์ฉ์์ ์ธ์ฆ ๋ฐ ๊ถํ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค.CustomUserDetailsService์์ ๊ฐ์ ธ์จ ํ์ ์ ๋ณด์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋น๊ตํ์ฌ ์ธ์ฆ์ ์ํํฉ๋๋ค.CustomUser(์ฌ์ฉ์ ์๋ณ ๋ฐ ์ธ์ฆ)
@Getter
public class CustomUser extends User {
public CustomUser(Member member) {
super(member.getEmail(), member.getPassword(), List.of());
}
}
ํด๋์ค๋ฅผ ์์๋ฐ์ User๊ฐ ๊ฐ์ง๊ณ ์๋ ์์ฑ์๋ฅผ ์ฌ์ฉํฉ๋๋ค. super("username","password","๊ถํ")์์ username์๋ Member์ ์ด๋ฉ์ผ, password์๋ Member์ password๋ฅผ ๋ฐ์์์ ์ธํ
ํฉ๋๋ค.CustomUserDetailsService์ loadUserByUsername`๋ฉ์๋์์ ์ฌ์ฉ์์ ์ ๋ณด๋ฅผ ๋ฐ์ ์ธ์ฆํฉ๋๋ค.User ํด๋์ค : ์ฌ์ฉ์์ ์ธ์ฆ ์ ๋ณด๋ฅผ ๋ํ๋ด๋ฉฐ ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ก๊ทธ์ธ ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํฉ๋๋ค. MemberService
public void signup(Member member) {
member.setPassword(encoder.encode(member.getPassword()));
mapper.insert(member);
}
BCryptPasswordEncoder๋ฅผ ์ฌ์ฉํ์ฌ ์ํธํํ๊ณ ์ํธํํ ๊ฒ์ ์ ์ฅํฉ๋๋ค.navbar.jsp
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<li class="nav-item">
<a href="/" class="nav-link">
๋ชฉ๋ก
</a>
</li>
<sec:authorize access="isAuthenticated()">
<li class="nav-item">
<a href="/add" class="nav-link">
๊ธ์ฐ๊ธฐ
</a>
</li>
<li class="nav-item">
<a href="/member/list" class="nav-link">
ํ์๋ชฉ๋ก
</a>
</li>
</sec:authorize>
<sec:authorize access="not isAuthenticated()">
<li class="nav-item">
<a href="/member/signup" class="nav-link">
ํ์๊ฐ์
</a>
</li>
<li class="nav-item">
<a href="/member/login" class="nav-link">
๋ก๊ทธ์ธ
</a>
</li>
</sec:authorize>
<sec:authorize access="isAuthenticated()">
<li class="nav-item">
<a href="/logout" class="nav-link">
๋ก๊ทธ์์
</a>
</li>
</sec:authorize>
<sec:authorize access="isAuthenticated()"> : ๋ก๊ทธ์ธ ํ๊ณ ์ฌ์ฉ์๊ฐ ์ธ์ฆ๋์์ ๋ ํด๋น ๊ธฐ๋ฅ์ ๋ณด์ฌ์ค๋๋ค.<sec:authorize access="not isAuthenticated()"> : ๋ก๊ทธ์ธ์ด ๋์ง ์์ ์ ๊ทผ์ด ์ ํ๋์ด ์ผ๋ถ ๊ธฐ๋ฅ๋ง ๋ณด์ฌ์ค๋๋ค.