Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- http
- Spring Boot
- Servlet
- 백준
- java
- transaction
- Greedy
- Proxy
- kotlin
- SpringBoot
- pointcut
- JPQL
- 그리디
- 자바
- Exception
- 알고리즘
- QueryDSL
- 인프런
- AOP
- JDBC
- jpa
- 스프링
- 김영한
- Thymeleaf
- db
- spring
- Android
- 스프링 핵심 원리
- 스프링 핵심 기능
- springdatajpa
Archives
- Today
- Total
개발자되기 프로젝트
[로그인] Servlet Filter - 인증 체크 본문
로그인 하지 않은 사용자가 상세 페이지 또는 앞으로 추가될 페이지에 접근하는 것을 막고싶다.
1. LoginCheckFilter class
- whitelist : 필터를 적용하지 않을 url 지정. ->회원등록, 로그인, 로그아웃, css관련 url은 해당 로직과 관계 없음.
- isLoginCheckPath() : 요청 url이 whitelist인지 아닌지 확인. PatternMatchinUtils를 사용하면 쉽게 비교 가능.
@Slf4j
public class LoginCheckFilter implements Filter {
//얘네들은 필터 적용 안됨.
private static final String[] whitelist = {"/", "/member/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)) {
log.info("인증 체크 로직 실행 {}", requestURI);
HttpSession session = httpRequest.getSession(false);
if (session == null || session.getAttribute(SessionConst.LOGIN_MEMBER) == null) {
log.info("미인증 사용자 요청 {}", requestURI);
//로그인으로 redirect
//redirectURL 추가 : 로그인 페이지로 이동 후 로그인 성공시 현재 페이지로 redirect
httpResponse.sendRedirect("/login?redirectURL=" + requestURI);
return ; //servlet 호출, controller호출 안함.
}
}
chain.doFilter(request, response);
} catch (Exception e){
throw e;//예외 로깅 가능하지만, 톰캣까지 예외를 보내줘야함.
}finally {
log.info("인증 체크 필터 종료 {}", requestURI);
}
}
/**
* whitelist의 경우 인증체크 안함.
*/
private boolean isLoginCheckPath(String requestURI){
return !PatternMatchUtils.simpleMatch(whitelist, requestURI);
}
}
- whitelist = {"/", "/members/add", "/login", "/logout","/css/*"};
- 인증 필터를 적용해도 홈, 회원가입, 로그인 화면, css 같은 리소스에는 접근할 수 있어야 한다.
- 이렇게 화이트 리스트 경로는 인증과 무관하게 항상 허용.
- 화이트 리스트를 제외한 나머지 모든 경로에는 인증 체크 로직을 적용
- isLoginCheckPath(requestURI)
- 화이트 리스트를 제외한 모든 경우에 인증 체크 로직을 적용한다.
- httpResponse.sendRedirect("/login?redirectURL=" + requestURI);
- 미인증 사용자는 로그인 하라고 로그인 화면으로 보내버린다.
- 이때 사용성 개선을 위해 현재 URL 정보를 QueryParamter로 같이 넘겨준다.
- LoginController에서 해당 queryParam을 받아 현재(거절된 페이지)페이지로 redirect 시키면 된다.ㅏ
- http://localhost:8080/login?redirectURL=/items
- return;
- 필터를 더는 진행하지 않는다.
- 이후 필터는 물론 서블릿, 컨트롤러가 더는 호출되지 않는다.
- 앞서 redirect 를 사용했기 때문에 redirect 가 응답으로 적용되고 요청이 끝난다.
2. Filter 등록
- 모든 요청에 대해 log남기는 filter다음으로 적용.
@Bean
public FilterRegistrationBean loginCheckFilter(){
FilterRegistrationBean<Filter> filterFilterRegistrationBean = new FilterRegistrationBean<>();
filterFilterRegistrationBean.setFilter(new LoginCheckFilter());
filterFilterRegistrationBean.setOrder(2);
filterFilterRegistrationBean.addUrlPatterns("/*"); //모든 url 적용
return filterFilterRegistrationBean;
}
3. LoginController
- 미인증 사용자가 인증에 실패하여 로그인 화면으로 redirect되는 경우.
- 거절된 페이지 url을 queryParam으로 같이 넘겨준다.
- @RequestParam을 통해 해당 queryparam을 받는다.
- 이 때 defaultValue를 "/"로 지정하여 queryParam이 없는 경우(최초 접근)는 home 으로 redirect!!
- http://localhost:8080/login?redirectURL=/items
@PostMapping("/login")
public String loginV4(@Validated @ModelAttribute("loginForm") LoginForm form,
BindingResult bindingResult,
@RequestParam(defaultValue = "/") String redirectURL,
HttpServletRequest request){
if(bindingResult.hasErrors()){
return "login/loginForm";
}
Member loginMember = loginService.login(form.getLoginId(), form.getPassword());
if(loginMember == null){
bindingResult.reject("loginFail", "id 또는 pw가 맞지 않습니다.");
return "login/loginForm";
}
//로그인 성공 처리
//세션이 있으면 있는 세션 반환, 없으면 신규 세션 생성 후 반환.
HttpSession session = request.getSession(true);
//세션에 로그인 회원 정보를 보관
session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember);
return "redirect:"+redirectURL;
}
4. 정리
- 서블릿 필터를 잘 사용한 덕분에 로그인 하지 않은 사용자는 나머지 경로에 들어갈 수 없게 되었다.
- 공통 관심사를 서블릿 필터를 사용해서 해결한 덕분에 향후 로그인 관련 정책이 변경되어도 이 부분만 변경
5. GitHub : 210926 Certification check
'인프런 > [인프런] 스프링 MVC 2' 카테고리의 다른 글
[로그인] Spring Interceptor - 요청 로그 (0) | 2021.09.26 |
---|---|
[로그인] 스프링 인터셉터 (0) | 2021.09.26 |
[로그인] Servlet Filter - 요청 로그 (0) | 2021.09.26 |
[로그인] Servlet Filter (0) | 2021.09.26 |
[로그인] Session 정보와 TimeOut 설정 (0) | 2021.09.26 |
Comments