simDev1234
심플하고 차분하게
simDev1234
전체 방문자
오늘
어제
  • 분류 전체보기
    • Computer Science
      • Basic Math
      • Data Structure
      • Algorithm
      • Database
      • OS
    • Language
      • Java
      • Kotlin
      • SQL
    • Framework
      • Spring
      • Orm&Mapper
      • 프로젝트로 스프링 이해하기
      • 스프링 라이브러리
    • Infra
      • Cloud
      • Docker
      • Redis
      • AWS, Azure
      • Device
    • Etc
      • CleanCoding
    • Git,Github

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 스프링
  • 404
  • null
  • 자바프로그램
  • 자바
  • 컨트롤러
  • JVM메모리구조
  • 참조변수
  • 자바메모리구조
  • 참조타입
  • controllerTest
  • 자바프로그래밍
  • scanner #next() #nextLine()

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
simDev1234

심플하고 차분하게

Framework/프로젝트로 스프링 이해하기

[LMS 만들기] 관리자 로그인 구현

2022. 10. 4. 13:06

|  사전 작업

1. 관리자 페이지

- 관리자페이지는 말그대로 관리자용 페이지를 말한다. 

- 사용자단과 구분되어지는 부분인데, 주로 아래와 같이 admin, backoffice.. 등의 키워드를 추가해놓는 형식이라한다.

- (개인적인 경험으로는 dev를 붙이기도 하는 걸 보기도 했다).. 그냥 붙이기 나름 같다.

- 수업에선 미리 관리자용 뷰를 작성하고, Controller로 주소를 매핑했다.

- 조금 특이했던 점은, 강사분은 사용자단과 관리자단을 구분하기 위해 컨트롤러의 논리주소에 .do를 추가했다는 점.

  * 이 부분은 사람들마다 조금씩 사용법이 다를 것 같은데, 미래에 일하게 될 회사에선 어떨지 궁금하다.

https://admin.fastlms.co.kr
https://backoffice.fastlms.co.kr

https://www.fastlms.co.kr/admin/
https://www.fastlms.co.kr/cms/
https://www.fastlms.co.kr/backoffice/

 

 

 

2. 회원 Entity에 관리자 여부를 파악할 수 있는 칼럼 추가

- 회원은 역할에 따라, 다양하게 나눠질 수 있다.

- Role : 준회원/정회원/무료회원/유료회언/특별회원/관리자

- 강사님은 ROLE_XXXX 식으로 회원을 구분한다고 하셨는데, 자체적으로 사용하는 방식을 따르면 될 것 같다.

- ex. ROLE_SEMI_USER, ROLE_USER, ROLE_SPECIAL_USER, ROLE_ADMIN

 

- 수업에서는 관리자 페이지를 만들고 다음으로 Member Entity에 관리자 여부를 파악하는 변수를 추가했었다.

- 이는 앞서 말했듯 비즈니스 환경에 따라 다양한 방식으로 적용이 가능할 것 같다.

  (수업 시, JPA 환경설정에 jpa.hibernate.ddl-auto.update 가 있어 Entity를 유연하게 수정이 가능했다.)

public class Member {
   // 추가된 부분
   private boolean adminYn;
}

 

|  Role에 따른 User 구분

- 기존에 Spring Security를 통해 로그인/로그아웃을 구현했었다.

- 지난번의 경우 사용자 페이지만을 작성하였기에, UserDetailsService를 상속한 @Service 객체의 LoadUserByUsername(String username) 메소드에, 사용자 Role만 추가했었다.

- 여기에 추가적으로 ADMIN 을 추가해주었다.

@Override
public UserDetails loadUserByUsername(String username)
        throws UsernameNotFoundException {

    // 사용자 Role 추가
    List<GrantedAuthority> grantedAuthorities = new ArrayList<>();

    grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_USER"));

    if (member.isAdminYn()) { // 관리자일 경우
        grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
    }

    return new User(member.getUserName(), member.getPassword(), grantedAuthorities);
}
더보기
@Override
public UserDetails loadUserByUsername(String username)
        throws UsernameNotFoundException {

    Optional<Member> optionalMember = memberRepository.findById(username);

    // validate
    if (!optionalMember.isPresent()) {
        throw new UsernameNotFoundException("회원 정보가 존재하지 않습니다.");
    }

    Member member = optionalMember.get();

    if (!member.isEmailAuthYn()) {
        throw new MemberNotEmailAuthException("이메일 활성화 이후 로그인 해주세요.");
    }

    // 사용자 권한, Role 추가
    List<GrantedAuthority> grantedAuthorities = new ArrayList<>();

    grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_USER"));

    if (member.isAdminYn()) { // 관리자일 경우
        grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
    }

    return new User(member.getUserName(), member.getPassword(), grantedAuthorities);
}

- 그런 다음, 지난 번에 작성한 SecurityConfig 클래스에 아래 사항을 추가해주었다.

  method 내용
1 hasAuthority("role") 해당 역할의 User만 접근 가능
2 exceptionHandling().accessDeniedPage("url") 접근 권한 없는 경우 해당 URL로 이동
@Override
protected void configure(HttpSecurity http) throws Exception {

        // hasAuthority("역할구분문자열")
        http.authorizeRequests()
                .antMatchers("/admin/**")
                .hasAuthority("ROLE_ADMIN");

        // 접근 불허 시 처리경로 추가
        http.exceptionHandling()
            .accessDeniedPage("/error/denied");

        super.configure(http);
}

 

더보기
/**
 * Http Security
 * 모두 접근 가능 : 홈, 회원 가입, 메일 인증
 */
@Override
protected void configure(HttpSecurity http) throws Exception {

    http.csrf().disable()
            .authorizeRequests()
            .antMatchers(
                    "/",
                    "/member/register",
                    "/member/email-auth",
                    "/member/find/password",
                    "/member/reset/password"
            )
            .permitAll();

    http.authorizeRequests()
            .antMatchers("/admin/**")
            .hasAuthority("ROLE_ADMIN");

    http.formLogin()
            .loginPage("/member/login")
            .failureHandler(getFailureHandler())
            .permitAll();

    http.logout()
            .logoutRequestMatcher(new AntPathRequestMatcher("/member/logout"))
            .logoutSuccessUrl("/")
            .invalidateHttpSession(true);

    http.exceptionHandling()
        .accessDeniedPage("/error/denied");

    super.configure(http);
}

- 그 후, DeniedPage 경로에 맞춰 템플릿(html)을 작성하고 잘 작동되는지를 확인했다.

 

|  정리

- 회원은 역할에 따라 다양하게 구분될 수 있다.

- Spring Security를 사용할 경우, 회원 역할에 사용자/관리자를 추가하여 관리자페이지에 대한 접근을 차단할 수 있다.

 

 

[ 출처 ]

부트캠프 수업 내용 정리

'Framework > 프로젝트로 스프링 이해하기' 카테고리의 다른 글

[LMS만들기] 회원 검색 기능 구현  (0) 2022.10.04
[LMS 만들기] JPA와 MyBatis로 회원 목록 구현  (1) 2022.10.04
[LMS 만들기] 비밀번호 초기화 요청 및 메일 링크를 통한 초기화  (1) 2022.10.04
[LMS 만들기] 스프링 시큐러티를 이용한 로그인/로그아웃  (0) 2022.10.03
[LMS 만들기] 회원가입 페이지 만들기  (0) 2022.10.02
    'Framework/프로젝트로 스프링 이해하기' 카테고리의 다른 글
    • [LMS만들기] 회원 검색 기능 구현
    • [LMS 만들기] JPA와 MyBatis로 회원 목록 구현
    • [LMS 만들기] 비밀번호 초기화 요청 및 메일 링크를 통한 초기화
    • [LMS 만들기] 스프링 시큐러티를 이용한 로그인/로그아웃
    simDev1234
    simDev1234
    TIL용 블로그. * 저작권 이슈가 있는 부분이 있다면 댓글 부탁드립니다.

    티스토리툴바