728x90
서블릿 로그인 필터 만들기
- 로그인을 했을 경우에만 특정한 페이지 접근을 허용하도록 하는 서블릿 필터
- whiteList 배열은 로그인 없이 접근 가능한 페이지들를 모아놓은 배열이다.
- doFilter 에서는 getRequestURI 를 통해서 서버로 요청된 uri 를 확인한다. 확인한 uri 에 대해서 isLoginCheckPath 메서드가 실행되는데 이 메서드를 통해서 해당 uri 가 whiteList - 접근 가능한 uri - 에 해당하는지 여부를 판단한다.
- 만약 isLoginCheckPath 가 true 를 출력한다면 해당 uri 는 로그인해야만 접근 가능한 uri 로 판정되고 다시 session 을 통해 세션의 null 여부와 session 안에 담긴 값을 조사한다.
- 즉 whiteList 배열에 속한 페이지가 아닌 경우는 filter 에 걸려서 session 검사를 받게 되고 세션이 없는 경우 로그인을 반드시 하도록 로그인 페이지로 보내게 된다.
- 이때 redirectURL 파라미터와 현재 uri 를 붙이게 되면 로그인 후 맨 처음 요청했던 uri 로 이동하기 위해서이다.
// 로그인 여부에 따른 페이지 접근 필터
@Slf4j
public class LoginCheckFilter implements Filter {
// whiteList 생성 => 로그인 상관없이 접근 가능한 페이지
private static final String[]whiteList= {"/", "/home", "/members/newregisters", "/login", "/logout"};
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
String reqURI = req.getRequestURI();
HttpServletResponse resp = (HttpServletResponse) response;
try {
log.info("인증 체크 필터 시작 {}", reqURI);
// 해당 uri 경로를 확인했을 때 만약 whiteList 에 해당하지 않는 경로라면
// 아래의 로직을 실행
if (isLoginCheckPath(reqURI)) {
log.info("인증 체크 로직 실행 {} ", reqURI);
// 현재 session 을 통해 로그인한 사용자인지 확인
HttpSession session = req.getSession(false);
// 만약 세션이 null 이거나 session 안에 담긴 정보가 없다면,
if (session == null || session.getAttribute(SessionConst.LOGIN_MEMBER) == null) {
log.info("미인증 사용자 요청 {} ", reqURI);
// 뒤에 redirectURL 을 찍어줌으로써 로그인 후 이전 페이지로 돌아올 수 있게 함
// 이전 페이지란 로그인하기 바로전에 간 페이지
resp.sendRedirect("/login?redirectURL=" + reqURI);
return;
}
}
chain.doFilter(request, response);
} catch (Exception e) {
throw e; // 예외 로깅도 가능하지만, 톰캣까지 예외를 보내주어야 함
}finally {
log.info("로그인 인증 체크 필터 종료");
}
}
/*
* 화이트 리스트의 경우 인증 체크 하지 않도록 하는 메서드
* */
private boolean isLoginCheckPath(String uri) {
// spring 에서 제공하는 PatternMatchUtil 을 통해서 uri 가 해당 whiteList 안에 있는지 확인
// 없다면 true, 있다면 false =>
return !PatternMatchUtils.simpleMatch(whiteList, uri);
}
}
SpringBean 설정
@Bean
public FilterRegistrationBean loginCheckFilterBean(){
FilterRegistrationBean<Filter> filterBean = new FilterRegistrationBean<Filter>();
filterBean.setFilter(new LoginCheckFilter());
// 필터 순서 => 필터 체인 시 사용되는 순서
// 이전 logFilter 가 살아있음으로 2번
filterBean.setOrder(2);
// 필수 적용 URL => 필터 적용 시 사용되는 url : /* 라면 모든 url 에 적용됨
filterBean.addUrlPatterns("/*");
return filterBean;
}
Controller 설정
- Controller 에서 로그인 후 이동하는 경로를 파라미터로 받아온 redirectURL 의 값으로 설정해주면 로그인 후 그곳으로 redirect 된다.
@PostMapping("/login")
public String loginWithHttpSession(@ModelAttribute LoginForm form,
BindingResult bindingResult,
HttpServletRequest request, HttpServletResponse res,
@RequestParam(name = "redirectURL", defaultValue = "/") String redirectURL
) throws IOException {
JSONObject jso = new JSONObject();
// 에러 관리 메서드(아직 사용 X)
// if (bindingResult.hasErrors()) {
// return "members/login";
// }
// 1. loginForm 을 통해 로그인 정보들을 가져옴
Member LoginMember = loginService.login(form.getLoginid(), form.getLoginpw());
Map<String, Object> result = new HashMap<String, Object>();
if (LoginMember == null) { // login 메서드에서 던져주는 값이 null 이면 로그인 실패
// bindingResult.reject("login Fail", "아이디 또는 비밀번호가 맞지 않습니다");
System.out.println("계정 정보 확인 불가. 로그인 실패");
res.setContentType("text/html;charset=utf-8");
// printWiter 객체는 java 단에서 javascript 를 사용할 수 잇게해주는 객체이다
// memberController 에서의 내용도 마찬가지로 이를 사용한 것.
PrintWriter out = res.getWriter();
result.put("state", "fail");
// out.println 으로 사용하자
out.println("<script>alert('로그인 실패!! 계정 정보를 확인해주세요');</script>");
out.flush(); // printwriter 종료
return "members/login";
} else if (form.getLoginid() == null || form.getLoginpw() == null) {
System.out.println("아이디나 비밀번호 중 null 값 존재");
res.setContentType("text/html;charset=utf-8");
// printWiter 객체는 java 단에서 javascript 를 사용할 수 잇게해주는 객체이다
// memberController 에서의 내용도 마찬가지로 이를 사용한 것.
PrintWriter out = res.getWriter();
result.put("state", "fail");
// out.println 으로 사용하자
out.println("<script>alert('아이디나 비밀번호가 비어있어요! 확인해주세요');</script>");
out.flush(); // printwriter 종료
return "members/login";
}
// 2. null 이외의 값 즉 member 객체라면 로그인 성공 처리
// http 서블릿 세션을 활용하기 위해서는 httpservlerequest 가 필요함 : 세션이 있으면 세션 반환, 없으면 세션 생성
// 이때 request.getSession() 에서 getSession() 의 파라미터안에는 true, false 두가지가 올 수 있음
HttpSession session = request.getSession();
// 세션에 회원 정보(LoginMember) 저장 후 홈으로 반환
session.setAttribute(SessionConst.LOGIN_MEMBER, LoginMember);
/** 이렇게 세션에 별도의 다른 값을 넣어 둘 수 있음 **/
session.setAttribute("memberCode", LoginMember.getMEMBERCODE());
log.info("redirectURL = {}", redirectURL);
return "redirect:" + redirectURL;
}
코드 확인
로그인 없이 member/memberList 에 접근한 모습
admin 으로 로그인 후 다시 회원리스트 - member/memberList 에 접근을 시도하였다 -
접근 가능한 것이 확인된다!
'Java - Spring &&n SpringBoot' 카테고리의 다른 글
Spring - ArgumentResolver (feat.커스텀 어노테이션, 세션) (0) | 2022.08.17 |
---|---|
Spring - 스프링 인터셉터(3) 스프링 인터셉터 개념과 로그 남기기 (0) | 2022.08.13 |
Spring - 서블릿 필터와 스프링 인터셉터(1) 서블릿필터, 서블릿 필터를 사용한 로그 찍기 (0) | 2022.08.11 |
Spring Session 다루기 : 세션 정보, 세션 타임 아웃 설정 (0) | 2022.08.11 |
Spring Boot - 회원가입 시 인증 메일 발송(feat.네이버 이메일 연결) (19) | 2022.08.08 |
댓글