판매자,고객,운영자 로그인여부, 로그기록 코드들

HUGO·2022년 9월 21일
0

mybatis

목록 보기
1/6

HandlerInterceptor

Java Web Programming에서의 Filter 역할을 수행하는 인터페이스
Controller(Servlet)가 요청을 처리하기 전이나 후에 수행할 동작을 작성할 수 있는 객체
Spring 프로젝트에서는 Filter 를 잘이용하지 않는데 Filter는 Spring과 무관하게 동작하기 때문에 Spring의 bean 들을 사용할 수 없어서 대부분 HandlerInterceptor 를 사용함
이렇게 프로그래밍 하는 이유는 사용자의 요청 처리와 직접적으로 연관이 없는 코드가 연관있는 코드와 같이 있게되면 프로그램을 읽는게 어려워지기 때문에 연관이 없는 코드는 별도로 작성한 후 애플리케이션이 컴파일 할 때 나 실행할 때 삽입하도록 해서 프로그램의 가독성을 높이고 프로그램을 쉽게 만들기 위해서
유사한 목적으로 사용되는 것이 자바의 어노테이션.

적용방법
HandlerInterceptor 인터페이스나 HandlerInterceptorAdapter 클래스를 상속받은 클래스를 생성하고 필요한 메소드를 재정의

메소드는 요청을 처리하기 전, 요청을 정상적으로 처리한 후, 요청을 처리하면 무조건 호출되는 메소드 3가지가 있음.

DispatcherServlet(servlet-context.xml) 파일에 어떤 URL 패턴에 인터셉터가 적용되도록 할 지 설정하면 됌.

많이 사용하는 경우
로그인 여부(Authentication), 권환확인(Authorization)
로그 기록 - 대부분은 별도의 프로그램 이용
성능 테스트 - 시간에 관련된 부분

config.java파일로 설정

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Autowired
    CustomLoginSuccessHandler customLoginSuccessHandler;

    @Autowired
    CustomLogoutSuccessHandler customLogoutSuccessHandler;

    @Autowired
    CustomDetailsService CustomDetailsService;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http)
    throws Exception {

        // 페이지 별 권한 설정
        http.authorizeRequests()
        .antMatchers("/admin", "/admin/**").hasAuthority("ADMIN")
        .antMatchers("/seller", "/seller/**").hasAnyAuthority("ADMIN" ,"SELLER")
        .antMatchers("/customer", "/customer/**").hasAuthority("CUSTOMER")
        .anyRequest().permitAll();


        // 로그인 페이지 설정
        // GET은 화면은 직접 생성 할거임 POST는 여기서(security) 사용.
        // 127.0.0.1:8080/BOOT1/member/login.do
        //<form th:action="@{/member/loginaction.do}" method="post">
        // <input type="text" name="userid" />

        http.formLogin()
            .loginPage("/member/login.do")                  // 로그인 페이지 설정
            .loginProcessingUrl("/member/loginaction.do")   // 로그인 하기 위한 페이지  
            .usernameParameter("userid")                    // 로그인 하는 아이디
            .passwordParameter("userpw")                    // 로그인 하는 비밀번호
            .successHandler(customLoginSuccessHandler)
            //.defaultSuccessUrl("/home.do")                  // 로그인 성공한 후 이동할 페이지
            .permitAll();

        // 로그아웃 => GET은 불가, POST로 사용.
        http.logout()
            .logoutUrl("/member/logoutaction.do")       // 로그아웃하기 위한 페이지
            //.logoutSuccessUrl("/home.do")               // 로그아웃 성공한 후 이동할 페이지
            .logoutSuccessHandler(customLogoutSuccessHandler)
            .invalidateHttpSession(true)
            .clearAuthentication(true)
            .permitAll();

        http.userDetailsService(CustomDetailsService);
        
        // 접근 불가 페이지 설정
        http.exceptionHandling().accessDeniedPage("/page403.do");

        // 보안 취약(비권장)
        // http.csrf().disable();


        // 일부의 주소만 csrf를 해제
        // http.csrf().ignoringAntMatchers("/h2-console/**");
        // http.headers().frameOptions().sameOrigin();

        return http.build();
    }
    
    
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

컨트롤러에 사용하기 전에 handlerInterseptor.java 파일로 각자의 사이트로 이동하기 위한 설정


@Component
@Slf4j
public class CustomHandlerInterceptor implements
            HandlerInterceptor{
    final String format = "INTERCEPTOR => {}";
        
    // 컨트롤러 진입후 view 표시전에 수행
    @Override
    public void postHandle(
            HttpServletRequest request, 
            HttpServletResponse response, 
            Object handler,
            ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
        log.info(format, "postHandle");
    }

    // 컨트롤러 진입전에 수행
    @Override
    public boolean preHandle(
            HttpServletRequest request, 
            HttpServletResponse response, 
            Object handler) throws Exception {

        log.info(format, "preHandle");    
        HttpSession httpSession = request.getSession();                
        
        if( request.getQueryString() == null) {
            httpSession.setAttribute("CURRENT_URL", 
                request.getContextPath() + request.getServletPath());
        }
        else {
            httpSession.setAttribute("CURRENT_URL", 
                request.getContextPath() + request.getServletPath()
                + "?" +  request.getQueryString());
        }
        System.out.println((String) httpSession.getAttribute("CURRENT_URL") );
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }
}

CustomLoginSuccessHandler.java 파일로 로그인 후 각 권한자의 세션 나누기


@Component
public class CustomLoginSuccessHandler 
        implements AuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(
        HttpServletRequest request, 
        HttpServletResponse response,
        Authentication authentication) throws IOException, ServletException {
        
        // 필요한 기능. 권한에 따라서 이동하는페이지를 다르게 구현
        // 시큐리티는 권한을 여러개 보관하기 위해서 Collection<>
        String role = authentication.getAuthorities().toArray()[0].toString();
        System.out.println("_-------------------------------------------------------");
        System.out.println(role);  
        System.out.println("_-------------------------------------------------------");
        HttpSession httpSession = request.getSession();  
        
        if(role.equals("CUSTOMER")) {
            // 세션에서 꺼냄
            String currentUrl = (String) httpSession.getAttribute("CURRENT_URL");
            System.out.println("aaa");
            System.out.println(currentUrl);
            if(currentUrl == null){ //세션정보 없음
                response.sendRedirect( 
                    request.getContextPath() + "/customer/home.do" );
            }
            else { // 세션정보가 있다면 가장 마지막 세션기록 URL로 이동
                response.sendRedirect(currentUrl);
            }
        }
        else if(role.equals("SELLER")) {
            response.sendRedirect(   
                request.getContextPath() + "/seller/home.do" );
        }
        else if(role.equals("ADMIN")) {
            response.sendRedirect(  
                request.getContextPath() + "/admin/home.do" );
        }
    }
    
}

CustomLoginSuccessHandler.java (로그아웃할때는 home으로)

@Component
public class CustomLogoutSuccessHandler
implements LogoutSuccessHandler {

    // 필요한 기능들을 여기에 구현
    @Override
    public void onLogoutSuccess(
        HttpServletRequest request, 
        HttpServletResponse response, 
        Authentication authentication)
            throws IOException, ServletException {
        response.sendRedirect(request.getContextPath() + "/home.do");
    }
    
}
profile
갓 신생아 개발자 이야기

0개의 댓글