2023. 7. 7. 15:35ใSpring
**์ํ๋ฆฌํฐ๋ css ๋ js ๋ฑ ๊ฐ์ด ์์ผ๋ฉด ์ถฉ๋๋จ
Securityconfig์ ์ค์ ํ๋ ์ฝ๋ ์์ฑํด์ผ ํจ.
//css, js, img ๋ฑ ์ถฉ๋ ์ ๋๊ฒ ํ๋ ์ฝ๋
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().requestMatchers("/js/**", "/css/**", "/img/**");
}
ํ์๊ฐ์ ์ ๋น๋ฐ๋ฒํธ ์ํธํ ์ค์ .
> ์ํธํ ์ค์ ํ๋ ค๋ฉด ์ํธํ ๊ฐ์ฒด๋ฅผ ์์ฑํด์ผ ํจ.
SecurityConfig์ @Bean์ผ๋ก ๊ฐ์ฒด ๋ฑ๋กํด์ฃผ๋ฉด ๋จ.(์์น ์๊ด ์์)
//์ํธํ ๊ฐ์ฒด ์์ฑ
@Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
ํ์๊ฐ์ controller๊ฐ ์๋ MemberController์ ์ํธํ ๊ฐ์ฒด ๋ถ๋ฌ์ด
//์ํธํ ๊ฐ์ฒด
@Autowired
private PasswordEncoder encoder;
ํ์๊ฐ์ ๊ธฐ๋ฅ์ ๋น๋ฐ๋ฒํธ ์ํธํ ์์ ์ฝ๋ ์์ฑ.
//ํ์๊ฐ์
@PostMapping("/join")
public String join(MemberVO memberVO) {
//๋น๋ฐ๋ฒํธ ์ํธํ ์์
String encodePw = encoder.encode(memberVO.getMemPw());
memberVO.setMemPw(encodePw);
memberService.joinMember(memberVO);
return "redirect:/member/login";
}
์ํ๋ฆฌํฐ๋ก ๋ก๊ทธ์ธ ๋ฐฉ์ ๋ณ๊ฒฝ
> ๋ก๊ทธ์ธ ์๋์ผ๋ก ์คํ์์ผ์ฃผ๋ userDetailsServiceImpl ์์ฑํด์ผ ํจ.
์ํ๋ฆฌํฐ๊ฐ ๋ก๊ทธ์ธ ํ ์ ์๊ฒ UserDetails์ ๋ก๊ทธ์ธ ์ ๋ณด ์ธํ
๋ก๊ทธ์ธ ํ ์ ๋ณด๋ฅผ ์กฐํํ๋ ๋ฉ์๋ ์ฌ์ฉ์ ์ํด mapper ์์
์ด์ ์ ๋ก๊ทธ์ธํ๋ ์ฟผ๋ฆฌ๋ฅผ ์์ ํ๋ฉด ๋จ.
<!-- ๋ก๊ทธ์ธ ์ ๋ณด ์กฐํ ์ฟผ๋ฆฌ -->
<select id="login" resultMap="member">
SELECT MEM_ID
, MEM_NAME
, IS_ADMIN
, MEM_PW
FROM SPRING_BOARD_MEMBER
WHERE MEM_ID = #{memId}
</select>
์ฑ์์ค ๋น ๊ฐ์ด ํ๋๋ก ์ค์์
> Id๊ฐ๋ง ๋ฐ์์ค๊ฒ MemberService ๋ฉ์๋ ์์
//์ํ๋ฆฌํฐ ๋ก๊ทธ์ธ
MemberVO login(String memId);
MemberServiceImpl๋ ๋์ผํ๊ฒ ์์ .
//์ํ๋ฆฌํฐ ๋ก๊ทธ์ธ
@Override
public MemberVO login(String memId) {
return sqlSession.selectOne("memberMapper.login", memId);
}
UserDetailsServiceImpl๋ก ๋์์์ ๋ก๊ทธ์ธ ์ ๋ณด ๋ด๊ธฐ.
๋ฉ์๋ ์ฌ์ฉ์ ์ํด memberService ๊ฐ์ฒด ๋ค๊ณ ์์ผ ํจ.
@Resource ์ด๋ ธํ ์ด์ ์ผ๋ก ๊ฐ์ฒด ๊ฐ์ ธ์ค๊ธฐ.
@Service("userDetailsService")//๊ฐ์ฒด ์์ฑ
public class UserDetailsServiceImpl implements UserDetailsService {
@Resource(name = "memberService")
private MemberService memberService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//๋ก๊ทธ์ธ ์ ๋ณด ์กฐํ //๋ก๊ทธ์ธํ ๋ ์
๋ ฅํ id๋ฅผ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์์ด
MemberVO userInfo = memberService.login(username);
//๋ก๊ทธ์ธ ์ ์
๋ ฅํ ID๊ฐ ์๋ ๊ณ์ ์ธ ๊ฒฝ์ฐ ์์ธ ๊ฐ์ ๋ฐ์
if(userInfo == null) {
throw new UsernameNotFoundException("์ค๋ฅ");
}
//๋ก๊ทธ์ธ ์ ๋ณด ๋ด๊ธฐ
UserDetails user = User.withUsername(userInfo.getMemId())
.password(userInfo.getMemPw())
.roles(userInfo.getIsAdmin()) //๊ถํ์ด 'Y' / 'N' ์ผ๋ก ๋ค์ด์ด
.build();
return user;
}
}
SecurityConfig์ ํ์๊ฐ์ ๋ฐ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ ๋ชจ๋ ์ฌ์ฉ์ ์ ๊ทผ ํ์ฉํ๊ฒ ์ค์ .
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain (HttpSecurity security) throws Exception {
//์ธ์ฆ ์ธ๊ฐ ์ค์
security.csrf().disable()
.authorizeHttpRequests()
.requestMatchers("/board/list"
, "/member/join"
, "/member/login").permitAll()
//.requestMatchers(HttpMethod.POST ,"/join").permitAll() POST ๋ฐฉ์ ์ด๋๊ฒฝ๋ก๋ง ์ฌ์ฉํ๊ณ ์ถ์ ๊ฒฝ์ฐ
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/member/login")
.usernameParameter("memId")
.passwordParameter("memPw")
.loginProcessingUrl("/loginProcess") //๋ก๊ทธ์ธ ์๋ํ๋ ๊ฒฝ๋ก๋, ๋ก๊ทธ์ธ ํ๋ ํ์ด์ง ๊ฒฝ๋ก ๊ฐ์๋ ๋จ.
.defaultSuccessUrl("/member/loginResult", true) //๋ฌด์กฐ๊ฑด ํด๋น ํ์ด์ง๋ก ์ด๋ํ๊ฒ true ๋ฃ์ด์ค
//.failureUrl("/member/loginResult")
.failureHandler(getFailureHandler()) //์คํจํ์ ๋ ํด๋์ค ์คํ ๋จ (์คํจํ์ ๋ ํด๋์ค์์ ์ฌ๋ฌ ์กฐ์ ๊ฐ๋ฅ)
.permitAll();
return security.build();
}
//์ํธํ ๊ฐ์ฒด ์์ฑ
@Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
//css, js, img ๋ฑ ์ถฉ๋ ์ ๋๊ฒ ํ๋ ์ฝ๋
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().requestMatchers("/js/**", "/css/**", "/img/**");
}
}
๋ก๊ทธ์ธ ์คํจ ์ ์ง์ ํ ํด๋์ค๋ก ์ด๋
FailureHandler ํด๋์ค ์์ฑ
์ด ํด๋์ค๋ SimpleUrlAuthenticationFailureHandler ํด๋์ค๋ฅผ ์์ ๋ฐ์์ผ ํจ
SimpleUrlAuthenticationFailureHandler ํด๋์ค๋ ์คํจ ์ ์คํ๋๋ ๋ฉ์๋๋ฅผ ์ด๋ฏธ ๊ฐ์ง๊ณ ์์.
ํด๋น ๋ฉ์๋ ์ค๋ฒ๋ผ์ด๋ฉ ํด์ ์ฌ์ฉ.
@Override //์์ฒญ : ๋์ด์ค๋ ๋ฐ์ดํฐ ๋ฐ๊ธฐ ๊ฐ๋ฅ //์๋ต
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
//์์ธ ์ ๋ณด(๋ก๊ทธ์ธ ์คํจ ์ ํ๋์ง)
super.onAuthenticationFailure(request, response, exception);
}
FailureHandler ํด๋์ค์ ๋ํ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ค์ผ ๋ฉ์๋๋ฅผ ์คํํ ์ ์์.
Securityconfig๋ก ๋์๊ฐ์ ์คํจ ์ ์๋ํ FailureHandler ๊ฐ์ฒด ์์ฑ.
@Bean
//๋ก๊ทธ์ธ ์คํจ ์ ์คํ๋๋ ํด๋์ค ๊ฐ์ฒด ์์ฑ
public FailureHandler getFailureHandler() {
return new FailureHandler();
}
์ธ์ฆ ์ธ๊ฐ ์ค์ ํ๋ ์ฝ๋์์ ์คํจ ์ FailureHandler ํด๋์ค ์คํ ๋๊ฒ ๋งค๊ฐ๋ณ์๋ก getFailureHandler ๋ฉ์๋ ๋ฃ์ด์ค.
์ด์ ๋ก๊ทธ์ธ ์คํจ ์ ์๋ํ ์ฝ๋๋ฅผ FailureHandler์ ์์ฑ.
//๋ก๊ทธ์ธ ์คํจ ์ ์๋์ผ๋ก ์คํ๋๋ ํด๋์ค
public class FailureHandler extends SimpleUrlAuthenticationFailureHandler{
@Override //์์ฒญ : ๋์ด์ค๋ ๋ฐ์ดํฐ ๋ฐ๊ธฐ ๊ฐ๋ฅ //์๋ต
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
//์์ธ ์ ๋ณด(๋ก๊ทธ์ธ ์คํจ ์ ํ๋์ง)
//์๋ฌ ๋ฉ์ธ์ง
String eMsg = "";
//์ด๋ค ์์ธ๋์ ๋ฐ๋ผ ํด๋์ค๊ฐ ๋ค๋ฆ
if(exception instanceof BadCredentialsException) {
//์
๋ ฅํ ์์ด๋ ๋๋ ๋น๋ฐ๋ฒํธ๊ฐ ์๋ชป๋จ.
eMsg = "์์ด๋ ํน์ ๋น๋ฐ๋ฒํธ๋ฅผ ํ์ธํ์ญ์์ค.";
}
else if (exception instanceof UsernameNotFoundException ){
//์
๋ ฅํ ๊ณ์ ์ด ์์ ๋
eMsg = "ํด๋น ๊ณ์ ์ด ์กด์ฌํ์ง ์์ต๋๋ค.";
}
else {
eMsg = "์ ์ ์๋ ์ด์ ๋ก ๋ก๊ทธ์ธ์ ์คํจํ์์ต๋๋ค. ๊ด๋ฆฌ์์๊ฒ ๋ฌธ์ํ์ญ์์ค.";
}
//๋ก๊ทธ์ธ ์ ์
๋ ฅํ id๊ฐ (๋ก๊ทธ์ธ ์คํจ ์ ๋ก๊ทธ์ธ์ฐฝ์ ๋ค์ ๋์ฐ๊ธฐ ์ํจ)
String memId = request.getParameter("memId");
//๋ก๊ทธ์ธ ์คํจ ์ ํ์ด์ง ์ด๋
//์น ์์์ ์ ์ฉ๋๋ utf-8๋ก ๋ฌธ์์ด ์ธ์ฝ๋ฉ ํด์ผ ํจ. (์ธ์ฝ๋ฉ ์ ํ๋ฉด ์ํํ ๋ฐ์ดํฐ๋ก ์ธ์ํ์ฌ ์ ๋์ด๊ฐ)
eMsg = URLEncoder.encode(eMsg, "UTF-8");
setDefaultFailureUrl("/member/login?eMsg=" + eMsg + "&isError=true&memId=" + memId);
System.out.println(eMsg);
super.onAuthenticationFailure(request, response, exception);
}
}
๋ก๊ทธ์ธ ์คํจํ๋ฉด ๋ค์ ๋ก๊ทธ์ธ ์ฐฝ์ผ๋ก ๊ฐ๊ฒ ๋จ.
ํ์ด์ง ์ด๋ํ ๋ ์ค๋ฅ ๋ฉ์์ง์ isError(์ค๋ฅ๊ฐ ๋ฐ์ํ๋์ง ์ ํ๋์ง ์ฌ๋ถ) ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ๊ฐ๊ฒ ํจ.
๊ทธ๋ฆฌ๊ณ ์ด์ ์ ์ ๋ ฅํ id๋ ๋ฐ ์ ์๊ฒ id๊ฐ๋ ๊ฐ์ ธ๊ฐ๋ค.
MemberController ์์ฑ
๋ก๊ทธ์ธ ํ์ด์ง ์ด๋ controller์์ ์ค๋ฅ ๋ฉ์์ง, ์ค๋ฅ ๋ฐ์ ์ฌ๋ถ ๋ฐ์ดํฐ ๋ฐ์ ์ ์์.
์ค๋ฅ ๋ฉ์์ง ์ค๋ฅ ๋ฐ์ ์ฌ๋ถ ๋ฐ์ดํฐ๋ฅผ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์์ฃผ๊ณ ๋์ด์ค๋ ๋ฐ์ดํฐ ํ์๊ฐ(์คํจ ์๋ง ๋์ด์ด)์ด ์๋๊ธฐ ๋๋ฌธ์ @RequestParam ์ด๋ ธํ ์ด์ ์ฌ์ฉ.
๋ฐ์ดํฐ login.html๋ก ๋๊ธฐ๊ธฐ.
๋์ด์จ id ๊ฐ์ ์ปค๋งจ๋ ๊ฐ์ฒด memberVO์์ ๋ฐ์์ html๋ก ์๋ ์ ๋ฌ๋จ!
//๋ก๊ทธ์ธ ํ์ด์ง ์ด๋
@GetMapping("/login")
public String loginForm(MemberVO memberVO
//๋์ด์ค๋ ๋ฐ์ดํฐ ํ์ X(๋ก๊ทธ์ธ ์คํจ ์๋ง ๋์ด์ด)
, @RequestParam(required = false) String eMsg
, @RequestParam(required = false, defaultValue = "false") String isError
, Model model) {
model.addAttribute("eMsg", eMsg);
model.addAttribute("isError", isError);
return "content/member/login";
}
login.html์์ ์ค๋ฅ ๋ฉ์์ง ๋ฐ์ดํฐ์ ์ค๋ฅ ๋ฐ์ ์ฌ๋ถ ๋ฟ๋ ค์ค.
th:field๋ก memId ์ค์ ๋์ด ์๊ธฐ ๋๋ฌธ์ ์ด์ ์ ์ ๋ ฅํ id๋ฅผ value ๊ฐ์ผ๋ก ์๋์ผ๋ก ๊ฐ์ ธ์ด
<div>์์ด๋ <input type="text" th:field="*{memId}"></div>
<!-- ์ค๋ฅ ๋ฉ์์ง -->
<div th:if="${isError}" th:text="${eMsg}"></div>
<div>๋น๋ฐ๋ฒํธ <input type="password" th:field="*{memPw}"></div>
<div>
<input type="submit" value="๋ก๊ทธ์ธ">
<input type="button" value="ํ์๊ฐ์
" th:onclick="|location.href='@{/member/join}';|">
</div>
๋ก๊ทธ์ธ ์คํจํ๋ฉด ์๋์ฒ๋ผ ์ค๋ฅ ๋ฉ์์ง๊ฐ ๋จ๊ณ ์ด์ ์ ์ ๋ ฅํ id๊ฐ ๋์ด
์ด์ ์ํ๋ฆฌํฐ๊ฐ ๋ก๊ทธ์ธ ์๋์ผ๋ก ํด์ฃผ๊ธฐ ๋๋ฌธ์ MemberController์ ๋ก๊ทธ์ธ controller ์ญ์
๋ก๊ทธ์ธ ์ฑ๊ณต ์ ์๋จ์ ๋ก๊ทธ์ธํ ์ฌ๋์ ์ด๋ฆ ๋จ๊ฒ ์ค์ .
๋ก๊ทธ์ธ ์ฑ๊ณตํ๋ฉด /member/loginResult๋ก ํ์ด์ง ์ด๋
MemberController์ ํ์ด์ง ์ด๋ ๋ฉ์๋ ์์ฑ
//๋ก๊ทธ์ธ ํ ์ด๋ํ๋ ํ์ด์ง
@GetMapping("loginResult")
public String loginResult () {
return "content/member/login_result";
}
login_result.html ์์
์ํ๋ฆฌํฐ ๋ฌธ๋ฒ ์ฐ๋ ค๋ฉด html์ ์๋จ์ ์๋ ์ฝ๋ ์ถ๊ฐ
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
์ํ๋ฆฌํฐ ๋ฌธ๋ฒ ์ฌ์ฉํ์ฌ ๋ก๊ทธ์ธ ์ฑ๊ณต ์ alert ์ฐฝ ๋จ๊ฒ ์ฝ๋ ๋ณ๊ฒฝ.
<!-- ๋ก๊ทธ์ธ ์ฑ๊ณต -->
<div sec:authorize="isAuthenticated()">
<script type="text/javascript">
alert('๋ก๊ทธ์ธ ์ฑ๊ณต');
location.href='/board/list';
</script>
</div>
๋ก๊ทธ์ธ ์คํจ ์์ ์๋๋๋ ์ด์ ์ ์์ฑํ ์ฝ๋๋ ์ง์๋ ๋จ!
๋ค์ MemberController๋ก ๋์์์ ๋ณธ๊ฒฉ์ ์ผ๋ก ์ด๋ฆ ๋ฝ๋ ์ฝ๋ ์์ฑ.
๋ก๊ทธ์ธ ํ ์ด๋ํ๋ ํ์ด์ง controller์์ ๋ก๊ทธ์ธ ์ฑ๊ณต ์ ๋ก๊ทธ์ธํ ์ฌ๋์ ์ด๋ฆ์ ์ฐพ์์ ์ธ์ ์ ๋ฑ๋กํด์ผํจ.
์ํ๋ฆฌํฐ๋ ์ธ์ ์ ๋ก๊ทธ์ธํ ์ฌ๋์ด ์์ด๋ ๊ฐ๊ณผ ๊ถํ๋ง ๋ค๊ณ ์์ด์ ๋ฐ๋ก ์ด๋ฆ ๋ฝ์ ์ ์์.
์ฐ์ , ๋งค๊ฐ๋ณ์์ Authentication ์ถ๊ฐ ์ธ์ ์ ์ ์ฅ๋ ๋ฐ์ดํฐ ๋ฝ๊ธฐ
//๋ก๊ทธ์ธ ํ ์ด๋ํ๋ ํ์ด์ง
@GetMapping("loginResult")
public String loginResult (Authentication authentication, HttpSession session) {
//๋ก๊ทธ์ธ ์ฑ๊ณต ์ ๋ก๊ทธ์ธํ ํ์์ ์ด๋ฆ์ ์ฐพ์์ ์ธ์
์ ๋ฑ๋ก
User user = (User)authentication.getPrincipal();
return "content/member/login_result";
}
ํ์ฌ ๋ก๊ทธ์ธํ ์์ด๋ ๊ฐ์ ์ฌ๋์ ์ด๋ฆ์ ์กฐํํด์ผ ๋จ.
member-mapper์์ ์ด๋ฆ ์กฐํ ์ฟผ๋ฆฌ ์์ฑ
<!-- ๋ก๊ทธ์ธํ ์ฌ๋ ์์ด๋ ์กฐํ -->
<select id="getUserNameById" resultType="String">
SELECT MEM_NAME
FROM SPRING_BOARD_MEMBER
WHERE MEM_ID = #{memId}
</select>
MemberService ๋ฉ์๋ ์์ฑ
//๋ก๊ทธ์ธํ ํ์ ์ด๋ฆ ์ ๋ณด
String getUserNameById(String memId);
MemberServiceImpl ๋ฉ์๋ ๊ตฌํ
//๋ก๊ทธ์ธํ ์ฌ๋ ์ด๋ฆ ์กฐํ
@Override
public String getUserNameById(String memId) {
return sqlSession.selectOne("memberMapper.getUserNameById", memId);
}
MemberController ์์ฑ ๋ฉ์๋ ์คํ
์กฐํํ ํ์ ์ด๋ฆ์ ์ธ์ ์ ๋ฐ์ดํฐ ์ธํ
//๋ก๊ทธ์ธ ํ ์ด๋ํ๋ ํ์ด์ง
@GetMapping("loginResult")
public String loginResult (Authentication authentication, HttpSession session) {
//๋ก๊ทธ์ธ ์ฑ๊ณต ์ ๋ก๊ทธ์ธํ ํ์์ ์ด๋ฆ์ ์ฐพ์์ ์ธ์
์ ๋ฑ๋ก
User user = (User)authentication.getPrincipal();
String userName = memberService.getUserNameById(user.getUsername());
//์ธ์
์ ํ์ ์ด๋ฆ ์ธํ
session.setAttribute("userName", userName);
return "content/member/login_result";
}
header.html๋ก ๊ฐ์ ๋ก๊ทธ์ธํ ์ฌ๋ ์ด๋ฆ ๋ฟ๋ ค์ฃผ๋ฉด ๋จ.
<div sec:authorize="isAuthenticated()">
[[${session.userName}]]๋ ๋ฐ๊ฐ์ต๋๋ค.
<a th:href="@{/member/logout}">LOGOUT</a>
</div>
๋ก๊ทธ์ธ ์ฑ๊ณตํ๋ฉด ์๋์ฒ๋ผ ์๋จ์ ์ด๋ฆ ์ ๊ฐ์ ธ์ด.
์ํ๋ฆฌํฐ ๋ก๊ทธ์์ ๊ธฐ๋ฅ ์ค์ .
์ํ๋ฆฌํฐ๊ฐ ์๋์ผ๋ก ๋ก๊ทธ์์ ๊ธฐ๋ฅ ํด์ฃผ๊ธฐ ๋๋ฌธ์ MemberContoller์ ์ด์ ์ ์์ฑํ ๋ก๊ทธ์์ ์ปจํธ๋กค๋ฌ ์ญ์
SecurityConfig ์์ฑ
@Bean
public SecurityFilterChain filterChain (HttpSecurity security) throws Exception {
//์ธ์ฆ ์ธ๊ฐ ์ค์
security.csrf().disable()
.authorizeHttpRequests()
.requestMatchers("/board/list"
, "/member/join"
, "/member/login").permitAll()
//.requestMatchers(HttpMethod.POST ,"/join").permitAll() POST ๋ฐฉ์ ์ด๋๊ฒฝ๋ก๋ง ์ฌ์ฉํ๊ณ ์ถ์ ๊ฒฝ์ฐ
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/member/login")
.usernameParameter("memId")
.passwordParameter("memPw")
.loginProcessingUrl("/loginProcess") //๋ก๊ทธ์ธ ์๋ํ๋ ๊ฒฝ๋ก๋, ๋ก๊ทธ์ธ ํ๋ ํ์ด์ง ๊ฒฝ๋ก ๊ฐ์๋ ๋จ.
.defaultSuccessUrl("/member/loginResult", true) //๋ฌด์กฐ๊ฑด ํด๋น ํ์ด์ง๋ก ์ด๋ํ๊ฒ true ๋ฃ์ด์ค
//.failureUrl("/member/loginResult")
.failureHandler(getFailureHandler()) //์คํจํ์ ๋ ํด๋์ค ์คํ ๋จ (์คํจํ์ ๋ ํด๋์ค์์ ์ฌ๋ฌ ์กฐ์ ๊ฐ๋ฅ)
.permitAll()
.and()
.logout()
.logoutUrl("/member/logout")
.invalidateHttpSession(true) //๋ก๊ทธ์์ ํ๋ฉด ์ธ์
๋ฐ์ดํฐ ์ง์ฐ๋ ๊ฒ
.logoutSuccessUrl("/board/list");
return security.build();
}
logoutUrl์ header.html์ ๋ก๊ทธ์์ ๊ฒฝ๋ก ๋ง์ถฐ์ฃผ๋ฉด ๋จ!
๋ก๊ทธ์์ ๋ฒํผ์ ๋ก๊ทธ์ธ ํ์ ๋๋ง ๋ณด์ฌ์ผํ๊ธฐ ๋๋ฌธ์ ์ํ๋ฆฌํฐ ๋ฌธ๋ฒ์ผ๋ก ์ค์ .
์ถ๊ฐ์ ์ธ ๋ฒํผ ์ปจํธ๋กค
1. header.html์ ๋ก๊ทธ์ธ ๋ฐ ํ์ ๊ฐ์ ๋ฒํผ์ ๋ก๊ทธ์ธ ์ ํ ๊ฒฝ์ฐ์๋ง ๋ณด์ฌ์ผ ๋จ.
์ํ๋ฆฌํฐ ๋ฌธ๋ฒ ์ฌ์ฉํ์ฌ ๋ก๊ทธ์ธ ์ ํ ๊ฒฝ์ฐ์๋ง ๋ณด์ด๊ฒ ์ฝ๋ ์์ฑ.
2.board_list.html์ ๊ธ๋ฑ๋ก ๋ฒํผ ๋ก๊ทธ์ธ ํ ๊ฒฝ์ฐ๋ง ๋ณด์ด๊ฒ ์ค์ .
html ์๋จ์ ์ํ๋ฆฌํฐ ๋ฌธ๋ฒ ์ฝ๋ ์ถ๊ฐ
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
์๋์ฒ๋ผ ๋ก๊ทธ์ธํ ๊ฒฝ์ฐ๋ง ๋ณด์ด๊ฒ ์ฝ๋ ์ถ๊ฐ.
๊ธ ์์ธ ํ์ด์ง
1. ์์ธ๋ณด๊ธฐ ํ์ด์ง์ ํ๋จ์ ๊ฒ์๊ธ ์์ , ์ญ์ ๋ฒํผ ์ปจํธ๋กค
๋ก๊ทธ์ธ ๋์์ ๋๋ง ๋ฒํผ ๋ณด์ด๊ฒ ์ํ๋ฆฌํฐ ๋ฌธ๋ฒ์ผ๋ก ์ค์
๋ก๊ทธ์ธํ ์ฌ๋์ด ๊ธ ์์ฑํ ์ฌ๋๊ณผ ์ผ์น or ๊ด๋ฆฌ์์ธ ๊ฒฝ์ฐ(ROLE์ด 'Y')
์์ , ์ญ์ ๋ฒํผ ๋ณด์ฌ์ผ ํ๊ธฐ ๋๋ฌธ์ if๋ฌธ์ผ๋ก ์กฐ๊ฑด ์ค์
<div th:if="${board.boardWriter == #authentication.name}">
<input type="button" value="์ญ์ " th:onclick="goDelete([[${board.boardNum}]]);">
<input type="button" value="์์ " th:onclick="goUpdate([[${board.boardNum}]]);">
</div>
<!-- ๋ก๊ทธ์ธํ ์ฌ๋ == ๊ด๋ฆฌ์ -->
<div sec:authorize="hasRole('ROLE_Y')">
<div th:if="${board.boardWriter !== #authentication.name}">
<input type="button" value="์ญ์ " th:onclick="goDelete([[${board.boardNum}]]);">
<input type="button" value="์์ " th:onclick="goUpdate([[${board.boardNum}]]);">
</div>
</div>
2. ๋๊ธ ๋ฑ๋ก ๋ฒํผ ๋ก๊ทธ์ธ ํ์ ๋๋ง ๋ณด์ด๊ฒ
์คํ๋ง ๋ณด๋ ๊ถํ n - ์ผ๋ฐ์ฌ์ฉ์ y - ๊ด๋ฆฌ์