Spring Boot Board Project_17 로그인 필터

송지윤·2024년 4월 21일
0

Spring Framework

목록 보기
50/65

Filter (Servlet 에서 제공함 (Spring에서도 사용 가능))
걸러내는 거 + 추가하는 거

Spring 은 Servlet 기반 Web application Framework
내부적으로 Dispatcher Servlet 돌아가고 있음

Client 와 Dispatcher Servlet 사이
클라이언트 요청 / 응답 할 때 Filter 가 catch 할 수 있음

Interceptor (Servlet 제공 X (Spring 에서만 제공))
가로채는 거 + 넣어주는 거
전처리, 후처리
Dispatcher Servlet 이 Controller 로 요청을 보내기 전 혹은 Controller 가 응답을 가지고 Dispatcher Servlet 에게 응답을 보내기 전 + View (View Resolver) 가 완성된 다음에

Filter

Request 걸러주거나 추가
Response 걸러주거나 수정해서 되돌려줄 수 있음

로깅, 보안, 인증, 인코딩 변환 할 때 사용

요청주소를 catch 할 수 있음 session에 loginMember 가 없으면 못 넘어가게

응답값을 가지고 client 에 돌려줄 때 ex) 응답값이 한국어
영어로 바꿔서 돌려주기

[필터 클래스 생성 방법]
1. jakarta.servlet.Filter 인터페이스 상속 받아야함
2. doFilter() 메서드 오버라이딩

1. LoginFilter 생성

package com.home.board.common.filter;

import java.io.IOException;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

/* Filter : 요청, 응답 시 걸러내거나 추가할 수 있는 객체
 * 
 * [필터 클래스 생성 방법]
 * 1. jakarta.servlet.Filter 인터페이스 상속 받아야함
 * 2. doFilter() 메서드 오버라이딩
 * */

// 로그인이 되어있지 않은 경우 특정 페이지로 돌아가게 함
public class LoginFilter implements Filter{

	// 필터 동작을 정의하는 메서드
	@Override
	public void doFilter(ServletRequest request,
						ServletResponse response,
						FilterChain chain)
			throws IOException, ServletException {

		// ServletRequest  : HttpServletRequest의 부모 타입
		// ServletResponse : HttpServletResponse의 부모 타입
		
		// HTTP 통신이 가능한 형태로 다운 캐스팅해서 사용해야함
		HttpServletRequest req = (HttpServletRequest)request;
		HttpServletResponse resp = (HttpServletResponse)response;
		
		// 로그인이 되어있는 상태인지 아닌지 알아야함
		
		// Session 얻어오기
		HttpSession session = req.getSession();
		
		// 세션에서 로그인한 회원 정보를 얻어옴
		// 얻어왔으나, 없을 때 -> 로그인이 되어있지 않은 상태
		if(session.getAttribute("loginMember") == null) {
			
			// /loginError 요청 받아줄 Controller 에 재요청
			// resp를 이용해서 원하는 곳으로 리다이렉트
			resp.sendRedirect("/loginError");
		} else {
			
			// 로그인이 되어있는 경우
			
			// FilterChain
			// - 다음 필터 또는 Dispatcher Servlet 과 연결된 객체
			
			// 다음 필터로 요청/응답 객체 전달
			// (만약 다음 필터가 없으면 Dispatcher Servlet 으로 전달)
			chain.doFilter(request, response);
		}
		
	}
}

2. LoginFilter 가 언제 적용돼야하는지 FilterConfig 생성

package com.home.board.common.config;

import java.util.Arrays;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.home.board.common.filter.LoginFilter;

/* 만들어놓은 LoginFilter 클래스가 언제 적용될지 설정 */

@Configuration // 서버가 켜질 때 해당 클래스 내 모든 메서드가 실행됨
public class FilterConfig {

	@Bean // 반환된 객체를 Bean 으로 등록 : LoginFilter로 타입을 제한함
	public FilterRegistrationBean<LoginFilter> loginFilter() {
		// FilterRegistrationBean : 필터를 Bean 으로 등록하는 객체
		
		FilterRegistrationBean<LoginFilter> filter
			= new FilterRegistrationBean<>();
		
		// 사용할 필터 객체 추가
		filter.setFilter(new LoginFilter());
		
		// /myPage/* : myPage로 시작하는 모든 요청 필터링 해줄거
		String[] filteringURL = {"/myPage/*"};
		
		// 필터가 동작할 URL을 세팅
		// Arrays.asList(filteringURL)
		// -> filteringURL 배열을 List 로 변환
		filter.setUrlPatterns(Arrays.asList(filteringURL));
		
		// 필터 이름 지정
		filter.setName("loginFilter");
		
		// 필터 순서 지정
		filter.setOrder(1);
		
		return filter; // 반환된 객체가 필터를 생성해서 Bean 으로 등록
	}
}

3. localhost/loginError 받아줄 Controller

MainController

	// LoginFilter -> loginError 리다이렉트
	// -> message 만들어서 메인페이지로 리다이렉트
	@GetMapping("loginError")
	public String loginError(RedirectAttributes ra) {
		ra.addFlashAttribute("message", "로그인 후 이용해주세요.");
		return "redirect:/";
	}

URL에 localhost/myPage 접근하면 alert 창 뜸

0개의 댓글