BackEnd/스프링 MVC

서블릿 필터 - 인증 체크

연향동큰손 2025. 1. 4. 16:16

 구현 해야하는 기능

  1. 로그인을 하지 않은 유저는 허용되지 않은 페이지로 접근 불가(로그인 페이지로 이동)
  2. 허용되는 페이지들만 따로 설정
  3. 로그인 하지 않은 사용자가 앞으로 개발될 페이지에 대해서 접근 못하도록 하기

 

<로그인 된 사용자인지 체크>

package hello.login.web.filter;

import hello.login.web.SessionConst;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.PatternMatchUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@Slf4j
public class LoginCheckFilter implements Filter {

    private static final String[] whiteList = {"/", "/members/add","/login","/logout","/css/*"};
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String requestURI = httpRequest.getRequestURI();

        HttpServletResponse httpResponse = (HttpServletResponse) response; //다운케스팅

        try{
            log.info("인증 체크 필터 시작{}",requestURI);
            if(isLoginCheckPath(requestURI)) {
                HttpSession session = httpRequest.getSession(false);
                if (session == null || session.getAttribute(SessionConst.LOGIN_MEMBER) == null) {
                    log.info("미인증 사용자 요청 {}", requestURI);

                    httpResponse.sendRedirect("/login?redirectURL=" + requestURI);

                    return;
                }
            }
            chain.doFilter(request, response);
        } catch (Exception e) {
            throw e;
        }
        finally {
            log.info("인증 체크 필터 종료 {}",requestURI);
        }

    }

    /**
     *  화이트 리스트의 경우 인증 체크 X
     */
    private boolean isLoginCheckPath(String requestURI){
        return !PatternMatchUtils.simpleMatch(whiteList,requestURI);
    }
}

 

 

 

private static final String[] whiteList = {"/", "/members/add","/login","/logout","/css/*"};

로그인 하지 않은 사용자도 접속 가능한 페이지를 설정할 수 있다.

ex) 홈화면, 로그인 페이지, css 관련 페이지

 

 

 

 

try{
    log.info("인증 체크 필터 시작{}",requestURI);
    if(isLoginCheckPath(requestURI)) {
        HttpSession session = httpRequest.getSession(false);
        if (session == null || session.getAttribute(SessionConst.LOGIN_MEMBER) == null) {
            log.info("미인증 사용자 요청 {}", requestURI);

            httpResponse.sendRedirect("/login?redirectURL=" + requestURI);

            return;
        }
    }
    chain.doFilter(request, response);
}

 

whiteList에 있는 페이지가 아닌경우

  1. 세션에 로그인된 회원 정보가 있는지 체크
  2. 없으면 Login화면으로 리다이렉트
  3. return을 통해 뒤 로직이 실행되지 않도록 함

 

 

<webConfig에 loginCheckFilter 추가>

@Bean
public FilterRegistrationBean loginCheckFilter() {
    FilterRegistrationBean<Filter> filterRegistrationBean = new
            FilterRegistrationBean<>();
    filterRegistrationBean.setFilter(new LoginCheckFilter());
    filterRegistrationBean.setOrder(2);
    filterRegistrationBean.addUrlPatterns("/*");

    return filterRegistrationBean;
}

 


 

<로그인에 성공하면 처음 요청한 URL로 이동하는 기능 개발>

 

@PostMapping("/login")
public String loginV4(@Valid @ModelAttribute LoginForm form, BindingResult bindingResult,
                      @RequestParam(defaultValue = "/") String redirectURL,
                      HttpServletRequest request) {
    if (bindingResult.hasErrors()) {
        return "login/loginForm";
    }
    Member loginMember = loginService.login(form.getLoginId(),form.getPassword());
    log.info("login? {}", loginMember);
    if (loginMember == null) {
        bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다.");
        return "login/loginForm";
    }
    //로그인 성공 처리
    //세션이 있으면 세션 반환, 없으면 신규 세션 생성
    HttpSession session = request.getSession();
    //세션에 로그인 회원 정보 보관
    session.setAttribute(SessionConst.LOGIN_MEMBER,loginMember);

    return "redirect:"+redirectURL; //리다이렉트 주소
}