Spring Boot)Interceptor

메타플랫폼대표
|2024. 8. 13. 11:11
반응형

해당 사용자가 admin인지, 해당 사용자가 성인인지, 로그인 유무 check하기 위해서 필요한 로직 (Interceptor)

 

애초에 Controller로 접속자체를 못하게 문전에서 막는 방법이라고 생각하면 좋겠다.

 

[ Interceptor가 실행될 시에 적용되는 함수 ]

[ Interceptor가 적용될 경로 지정해주기 ]

 

 

[ pre와 post의 차이 ]

 

[ Interceptor 제외, 포함 Method ]

 

 

 


 

 

 

[ 생성하기 ]

 

 

 

[ JSP 환경설정 ]

pom 파일에 추가하기

		<dependency>
			<groupId>org.apache.tomcat.embed</groupId>
			<artifactId>tomcat-embed-jasper</artifactId>
		</dependency>


		<dependency>
			<groupId>jakarta.servlet</groupId>
			<artifactId>jakarta.servlet-api</artifactId>
			<version>6.0.0</version>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>jakarta.servlet.jsp.jstl</groupId>
			<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
			<version>3.0.0</version>
		</dependency>

		<dependency>
			<groupId>org.glassfish.web</groupId>
			<artifactId>jakarta.servlet.jsp.jstl</artifactId>
			<version>3.0.1</version>
		</dependency>

 

 

 

application.properties 추가하기

spring.application.name=demo_interceptor

spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp

 

 

 

LoggerInterceptor 생성하기

//@Slf4j <= Lombok설치하면 Log처리객체 자동처리

@Slf4j
public class LoggerInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("==================== BEGIN ====================");
        log.info("Request URI ===> " + request.getRequestURI());
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("==================== END ======================");
        log.info("===============================================");
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

}

 

 

 

Config 생성하기

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoggerInterceptor())
                .excludePathPatterns("/css/**", "/images/**", "/js/**");
    }

}
// addPathPatterns("/**")
// excludePathPatterns("/css/**", "/images/**", "/js/**") 또는 Method Chainning방식으로 처리해도 된다

 

 

 

Controller 등록하기

package com.githrd.demo_interceptor.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    @GetMapping("/home")
    public String home() {

        return "My Home";
    }

    @GetMapping("/hi")
    public String hi() {

        return "Hi~";
    }

}

 

 

 

[ 내가 add한 Patterns만 Interceptor 걸리게 하기 ]

 

 

[ 전체 경로가 Interceptor 걸리게 하기 ]

 

 

 

ex) admin과 adult 경로에 들어가있는 Method만 Interceptor가 일어나게 한다.

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoggerInterceptor())
                .addPathPatterns("/admin/**","/adult/**")
                .excludePathPatterns("/css/**", "/images/**", "/js/**");
    }

}

 

 

 

Controller 생성하기

    // login?name=홍길동&age=20&grade=normal  or  admin
    @GetMapping("/login")
    @ResponseBody
    public String login(@RequestParam Map<String, Object> user) {

        System.out.println(user);

        // 로그인 유저 정보 세션에 담는다.
        session.setAttribute("user", user);

        return "Login 완료";
    }

    @GetMapping("/logout")
    @ResponseBody
    public String logout() {

        // 세션에 들어간 유저를 삭제
        session.removeAttribute("user");

        return "Logout 완료 되었습니다.";
    }

 

 

 

임의적으로 로그인 할 수 있는 정보의 Method를 생성한다.

 

 

 

admin Interceptor를 걸어준 항목을 들어갈 수 있는 Controller 생성하기

 

 

 

관리자만 볼 수 있는 member_list jsp 생성하기

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <hr>
        회원목록
    <hr>

    <p>이름 : 일길동</p>
    <p>아이디 : hong1</p>
    <p>비밀번호 : 1234</p>
    <br>

    <p>이름 : 이길동</p>
    <p>아이디 : hong2</p>
    <p>비밀번호 : 1324</p>
    <br>

    <p>이름 : 삼길동</p>
    <p>아이디 : hong3</p>
    <p>비밀번호 : 4321</p>
    <br>

    <p>이름 : 사길동</p>
    <p>아이디 : hong4</p>
    <p>비밀번호 : 4351</p>
    <br>

    <p>이름 : 오길동</p>
    <p>아이디 : hong6</p>
    <p>비밀번호 : 5261</p>
    <br>


</body>
</html>

 

 

 

이제 Interceptor 할 수 있게 Method를 설정해주자 (admin으로 로그인을 받아야 한다)

@Slf4j
public class LoggerInterceptor implements HandlerInterceptor {

    
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 로그인 정보 얻어오기
        Map<String, Object> user = (Map<String, Object>) request.getSession().getAttribute("user");
        // 유저가 로그인 안 된 상태 (admin 이나 adult로 접속을 해야하기 때문에 로그인 유무 체크)
        if(user==null) {

            return false;
        }

        System.out.println("==================== BEGIN ====================");
        System.out.println("Request URI ===> " + request.getRequestURI());
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("==================== END ======================");
        System.out.println("===============================================");
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

}

 

 

 

user session 받아오게 설정했더니 잘들어가지던 화면이 하얀색 화면으로 들어가진다. (로그인이 안되어 있기 때문에)

 

 

 

@Slf4j
public class LoggerInterceptor implements HandlerInterceptor {

    
    
    @SuppressWarnings("unchecked")
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 로그인 정보 얻어오기
        Map<String, Object> user = (Map<String, Object>) request.getSession().getAttribute("user");
        // 유저가 로그인 안 된 상태 (admin 이나 adult로 접속을 해야하기 때문에 로그인 유무 체크)
        if(user==null) {

            response.sendRedirect("../myerror?reason=session_timeout");
            return false;
        }

        String uri = request.getRequestURI();
        // uri = /admin/memebers
        // uri = /adult/...

        if(uri.startsWith("/admin/")) {
            // 관리자페이지 유무
            String grade = (String) user.get("grade");
            if(!grade.equals("admin")) {

                response.sendRedirect("../myerror?reason=not_admin");
                return false; // grade 등급이 admin이 아닌 경우
            }
        } else if(uri.startsWith("/adult/")) {
            // 성인인지 검증

        }

        System.out.println("==================== BEGIN ====================");
        System.out.println("Request URI ===> " + request.getRequestURI());
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("==================== END ======================");
        System.out.println("===============================================");
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

}
    // /error?reason=session_timeout
    @GetMapping("/myerror")
    @ResponseBody
    public String error(String reason) {

        String message = "no_message";

        switch(reason)
        {
            case "session_timeout" : message = "로그아웃 되었습니다.";break;
            case "not_admin" : message = "현재 페이지는 관리자만 확인할 수 있습니다.";break;
        }

        return message;
    }

 

 

로그인 완료 (normal)

 

 

admin_page 접속불가

 

 

admin으로 다시 로그인

 

 

다시 관리 페이지 접속 하면 admin_page 접속 가능

 

 

 

    @SuppressWarnings("unchecked")
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 로그인 정보 얻어오기
        Map<String, Object> user = (Map<String, Object>) request.getSession().getAttribute("user");
        // 유저가 로그인 안 된 상태 (admin 이나 adult로 접속을 해야하기 때문에 로그인 유무 체크)
        if(user==null) {

            response.sendRedirect("../myerror?reason=session_timeout");
            return false;
        }

        String uri = request.getRequestURI();
        // uri = /admin/memebers
        // uri = /adult/...

        if(uri.startsWith("/admin/")) {
            // 관리자페이지 유무
            String grade = (String) user.get("grade");
            if(!grade.equals("admin")) {

                response.sendRedirect("../myerror?reason=not_admin");
                return false; // grade 등급이 admin이 아닌 경우
            }
        } else if(uri.startsWith("/adult/")) {
            // 성인인지 검증
            int age = Integer.parseInt((String) user.get("age"));

            if(age<20) {

                response.sendRedirect("../myerror?reason=not_adult");
                return false;
            }

        }

        System.out.println("==================== BEGIN ====================");
        System.out.println("Request URI ===> " + request.getRequestURI());
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("==================== END ======================");
        System.out.println("===============================================");
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

}
    // /error?reason=session_timeout
    @GetMapping("/myerror")
    @ResponseBody
    public String error(String reason) {

        String message = "no_message";

        switch(reason)
        {
            case "session_timeout" : message = "로그아웃 되었습니다.";break;
            case "not_admin" : message = "현재 페이지는 관리자만 확인할 수 있습니다.";break;
            case "not_adult" : message = "현재 페이지는 성인만 확인할 수 있습니다.";break;
        }

        return message;
    }

 

 

 

[ return true로 지정할 경우 ]

postHandle까지 출력이 된다.

반응형

'SpringBoot↗' 카테고리의 다른 글

Spring Boot)File Upload 파일업로드  (0) 2024.08.13
Spring Boot) AOP  (0) 2024.08.13
AWS 서버(프로젝트 업로드)  (0) 2024.08.13
Spring Boot)Transaction  (0) 2024.08.12
Spring Boot)JPA로 Sawon 데이터 활용하기  (0) 2024.08.12