#7 [스프링 스터디] 쇼핑몰 만들기 프로젝트 - 판매자/구매자 페이지 권한 설정 (Feat. sec:authorize)
쇼핑몰의 기능은 판매자와 구매자로 나누어 집니다.
브라우저에서 같은 메인 화면을 보더라도
- 판매자는 상품 등록, 수정, 삭제, 판매관리 등
- 구매자는 상품 구매, 장바구니, 마이페이지 등
의 기능을 사용할 수 있습니다.
AuthenticationEntryPoint 인터페이스 구현 클래스를 사용하여 인증되지 않은 사용자의 요청이 오면 "Unauthorized" 에러를 발생시키고, SecurityConfig 파일에서 HttpServletRequset 에 대해 security 를 처리하여 수행하는 방법이 있습니다. http.authorizeRequests.mvcMatchers("/seller/**").hasRole("ROLE_SELLER") 이런 식으로 작성하면 되지만 저는 이러한 방식이 아직은 어렵고 복잡하다고 느껴 스터디 팀원의 도움으로 감사하게도 조금 더 쉬운(?) 방식을 사용하여 권한을 설정하였습니다.
바로 Controller에서 if문을 활용하는 방식입니다.
이 방식은 유저 프로필 페이지에서 더 유용하게 쓰일 수 있으니 추후에 적용해 보아도 좋을 것 같습니다 :)
로그인을 하지 않은 유저, 구매자(ROLE_USER)로 로그인 한 유저, 판매자(ROLE_SELLER)로 로그인 한 유저로 각각 접속을 하면
<로그인 안 한 메인페이지>
<구매자 메인페이지>
<판매자 메인페이지>
이렇게 각각의 접근 권한에 따라 상단부의 메뉴 기능이 다른 메인페이지가 나와야 합니다.
로그인을 하지 않은 유저, 구매자(ROLE_USER)로 로그인 한 유저, 판매자(ROLE_SELLER)로 로그인 한 유저에 맞게 html 파일을 이렇게 3개 만들으면 됩니다.
사실 이렇게 파일을 나누면 중복되는 부분이 많습니다. 더 효율적인 방법으로는 main 이라는 html 파일 하나에 sec:authorize 을 써서 3개의 파일을 하나의 파일로 작성할 수도 있지만 이 방법은 조금 뒤에 설명하도록 하겠습니다.
// 메인 페이지 (로그인 안 한 유저) /localhost:8080
@GetMapping("/")
public String mainPageNoneLogin(Model model) {
// 로그인을 안 한 경우
List<Item> items = itemService.allItemView();
model.addAttribute("items", items);
return "/main";
}
// 메인 페이지 (로그인 유저) - 판매자, 구매자 로 로그인
@GetMapping("/main")
public String mainPage(Model model, @AuthenticationPrincipal PrincipalDetails principalDetails) {
if(principalDetails.getUser().getRole().equals("ROLE_SELLER")) {
// 어드민, 판매자
List<Item> items = itemService.allItemView();
model.addAttribute("items", items);
model.addAttribute("user", principalDetails.getUser());
return "/seller/mainSeller";
} else {
// 일반 유저일 경우
List<Item> items = itemService.allItemView();
model.addAttribute("items", items);
model.addAttribute("user", principalDetails.getUser());
return "user/mainUser";
}
}
Controller에서 우선 로그인을 안 한 유저와 로그인을 한 유저로 나눌 수 있습니다. 그리고 또 로그인을 한 유저는 판매자와 구매자로 나누어집니다.
@AuthenticationPrincipal 어노테이션을 통해 PrincipalDetails 를 매개변수로 받습니다.
조건문으로 현재 로그인 한 유저의 role을 get 하여 비교합니다. return 문을 보면 판매자일 경우 mainSeller로, 구매자일 경우 mainUser로 가는 것을 볼 수 있습니다.
이 방식은 상품 등록, 수정, 삭제에도 동일하게 사용됩니다.
상품 등록, 수정, 삭제 기능은 role 이 ROLE_SELLER인 유저에게만 가능하게끔 해야 하기 때문입니다.
> sec:authorize
이제 sec:authorize 를 사용한 방식을 알아보겠습니다.
html에 sec:authorize를 사용하면 위처럼 main을 세 개로 나누지 않아도 됩니다. 먼저 main.html 파일 상단의 html 태그에
xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
타임리프를 넣어줍니다!
그리고 권한을 따로 줘야하는 곳에 가서 sec:authorize 를 넣어주면 되는데요, main에서 로그인 버튼은 로그인을 하지 않은 유저에게만 보여야 합니다. 따라서
<form th:action="@{/signin}" sec:authorize="!isAuthenticated()">
<button class="btn btn-outline-dark" type="submit">
로그인
</button>
</form>
sec:authorize="!isAuthenticated()" 를 넣어주어 로그인을 하지 않았을 때 로그인 버튼이 보이도록 설정합니다.
로그아웃의 경우에는 로그인을 한 유저에게만 보여야 합니다. 따라서
<form th:action="@{/logout}" method="post" sec:authorize="isAuthenticated()">
<button class="btn btn-outline-dark" type="submit">
로그아웃
</button>
</form>
sec:authorize="isAuthenticated()" 를 넣어주면 되겠지요!
이 외에 sec:authorize="hasRole('ROLE_USER')"과 sec:authorize="hasRole('ROLE_SELLER')" 도 있습니다.
예를 들어 상품 등록 버튼에는 ROLE_SELLER를, 마이페이지 버튼에는 ROLE_USER를 사용합니다.
이렇게 sec:authorize를 사용하면 html 파일을 나누어 관리하는 것이 아닌 하나의 파일에서 관리할 수 있어 편리합니다!
저는 처음에 이 기능을 몰라서 html을 여러개 만들어 하나를 고치면 다른 파일도 고쳐야 하는 번거로움이 있었는데, sec:authorize를 사용하여 더 수월하게 코드를 수정할 수 있을 것 같습니다 :)
Author And Source
이 문제에 관하여(#7 [스프링 스터디] 쇼핑몰 만들기 프로젝트 - 판매자/구매자 페이지 권한 설정 (Feat. sec:authorize)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@rladuswl/7-스프링-스터디-쇼핑몰-만들기-프로젝트-판매자구매자-페이지-권한-설정-Feat.-secauthorize저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)