본문 바로가기

programming/웹프로그래밍

[spring] Interceptor와 Session의 개념과 구현, Clone Coding

반응형

1. 개요

 

 Clone Coding프로젝트를 마무리 한지 꽤 오랜 시간이 지났다. 프로젝트 도중 인턴에 합격한 팀원도 있고 다른 교육 프로그램에 합격한 팀원도 있다. 기쁜소식을 들어면서 프로젝트를 진행하니 나도 동기부여가 되는 것 같다. 중간고사가 끝나고 드디어 시간이 조금 나니, 조금씩 꾸준하게 블로그에 글을 올릴 생각이다.

 

2. 이론

 

 내 역활중 하나는 바로 admin페이지의 로그인을 구현하는 것. 사실 관리자 로그인은 데이터베이스에 아이디와 패스워드 한 세트만을 생성하고 그것을 쓰면 되기 때문에, 아이디와 비밀번호의 CRUD는 그렇게 어렵지 않았다. 중요한 것은 매 페이지마다 섹션에 있는 값을 확인하는 기능을 구현하는 것이다. 

 

 설명하자만 매번 검사하는 것은 Interceptor로 그리고 관리자가 로그인했다는 정보를 저장하는 것은 Session으로 구현한다고 생각하면 편할 것 같다.

 

- Interceptor

 

 인터셉터의 뜻을 알면 이해하기 쉬울 것 같다. 군대에서는 이를 요격기라는 뜻으로 쓰고 있고 축구선수들이 상대선수의 패스를 끊을 때 인터셉터했다고도 한다. 결국 인터셉터는 '가로채는 무언가' 라고 생각해도 좋을 듯 하다. 이 이름과 맞게 웹에서도 Interceptor는 가로채는 역할을 한다. 우리가 설정만 해주면 클라이언트에서 서버에 요청하기 직전 무조건 Interceptot를 한번 거쳐야 한다. 

 

 나는 이 Interceptor를 통해 admin page마다 interceptor를 거쳐 관리자가 로그인 했는지를 검사할 것이다.

 

- Session

 

 자 그럼 섹션은 무엇일까? 나는 기술을 잘 아는 개발자가 아니다. 정말 훌륭한 현직자들의 블로그처럼 기술을 깊이있게 설명할 수 없고 그럴 자격도 없다. 그저 그분들의 글을 읽고 그것을 내 프로젝트에 적용할 뿐이다. 이런 관점에서 본 Session은 나에게는 그저 하나의 공간이다. 서버에 데이터를 넣을 수 있는 공간. 나는 이 공간에 관리자의 아이디와 관리자의 비밀번호를 넣고 인터셉터에서 꺼낸 후 비교해줌으로써 관리자 로그인을 완성시켰다. 다음은 소스 코드이다.

 

2. 소스 코드

 

 인터셉터를 설정하려면 필요한 정보들이 있다. 일던 어떤 URL에서 interceptor를 거치게 할 것인가. 그리고 interceptor의 역할을 하는 실질적인 코드 즉 controller의 위치이다. 다음은 intercetor에 코드이다.

 

- dispatcher-servlet.xml

<mvc:interceptor>
    <mvc:mapping path="/admin/**" />
    <mvc:exclude-mapping path="/admin/login"/>
    <bean class="com.test.controller.adminLoginInterceptor" />
</mvc:interceptor>

 

 위의 코드를 보면 mapping이 interceptor를 거칠 URL이다. "admin/**" 으로 설정하면 admin/ URL에 상속되는 모든 URL들은 전부 interceptor를 거치게 된다.

 

 다음은 bean태그이다. 이는 위에서 말한 실질적인 interceptor역할을 하는 코드이 위치이다. 그리고 이 class에서 interceptor의 내용을 적어주면 된다. 

 

 또 하나의 코드가 있는데, 바로 exclude-mapping이다. 영어로 번역하면 '들어오지 못하게 하다.'라는 뜻을 가지고 있다. 말 그대로 인터셉터를 거치지 않을 URL을 적어주는 곳이다. 옆에 URL을 봄ㄴ "admin/login" 으로 이는 admin/ URL을 상속받는 주소로 인터셉터를 거쳐야 하지만 저렇게 exclude-mapping 태그안에 넣어주면 이 URL은 인터셉터를 거치지 않게 된다. 다음은 섹션을 사용하는 즉 interceptor역할을 하는 컨트롤러이다.

 

- adminLoginInterceptor.class

 

public class adminLoginInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    AdminLoginService adminloginService;


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

        System.out.println("Start adminLoginInterceptor session");

        HttpSession session = request.getSession(false);
        if (session != null) {
            Object admin = session.getAttribute("adminLogin");
            System.out.println("session is not null");
            if (admin != null) {
                System.out.println("adminLogin is not null");
                AdminLoginDto adminLog = (AdminLoginDto) admin;

                ArrayList<AdminLoginDto> loginInfo = adminloginService.getLoginInfo();
                AdminLoginDto result = loginInfo.get(0);

                if (adminLog.getId().equals(result.getId()) &&
                        adminLog.getPassword().equals(result.getPassword())) {
                    return true;
                }
            } else {
                System.out.println("adminLogin is null");
            }
        } else {
            System.out.println("session is null");
        }
        response.sendRedirect("/admin/login");
        return false;
    }
}

 

 위에는 session을 불러오고 session에 저장된 값을 확인하는 코드이다. 관리자의 아이디와 비밀번호를 가변리스트 형태를 통해 저장하였고 이를 불러와 하나씩 비교해주는 코드이다. 중요한 점은 session을 통해 이들을 확인한다는 것이다.

 

3. 결어

 

 사실 문법적인 설명을 많이 하고 싶었지만 최근 딜레마에 빠졌다... 코딩테스트와 실질적인 포트폴리오에 대한 많은 내용을 듣고 스스로를 발전시키는 과정이라고 생각하며 노력하고 있다. 조금더 완벽하게 문법을 공부하고 이 블로그에 글을 올렸으면 좋겠다.

반응형