학습 목표 

1. 세션 활용해 보기 
2. 인증된 사용자 여부를 인터셉터에서 확인하고 페이지 이동 처리 하기 

시나리오 코드 결과물 
클라이언트는 login.html 파일에는 누구나 접근할 수 있는 페이지로 만들기 
클라이언트는 mypage/myinfo.html 파일에는 인증 된 사용자만 접근 하게 만들기 
클라이언트는 mypage/cart.html 파일에는 인증 된 사용자만 접근 하게 만들기

사전 기반 지식

Spring Boot에서 기본적으로 제공하는 세션은 내장형 서버(Tomcat, Jetty 등)를 사용할 때, 
메모리 기반 세션을 사용합니다. 따라서 세션 데이터는 서버의 메모리에 저장됩니다.

내장형 서버의 경우 server.servlet.session.* 프로퍼티를 사용하여 세션 관련 설정을 할 수 있습니다.
예를 들어 다음과 같이 application.properties 파일에서 설정할 수 있습니다.

# 세션 타임아웃 설정 (기본값: 30분)
server.servlet.session.timeout=60

# 세션 쿠키 이름 설정 (기본값: JSESSIONID)
server.servlet.session.cookie.name=MYSESSIONID

# 세션 쿠키 경로 설정 (기본값: /)
server.servlet.session.cookie.path=/

Spring Boot에서 제공하는 세션은 서버의 메모리에 저장되므로, 서버를 재시작하면 세션 데이터가 모두
삭제됩니다. 이러한 한계를 극복하기 위해서는 세션 클러스터링, 분산 캐시 등의 기술을 이용하여 
세션 데이터를 외부 저장소(디스크, 데이터베이스, 분산 캐시 등)에 저장할 수 있습니다.

HttpSession은 서버 메모리에 생성되는 세션 객체이며, 사용자의 요청마다 새로운 HttpSession 객체가 생성됩니다.
이때 Spring Container는 Servlet Container와 함께 사용되어, 
HttpSession 객체에 접근하여 세션 데이터를 저장하거나 가져올 수 있습니다.

시나리오 코드 1

UserController 만들어 보기

package com.example.demo9.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import com.example.demo9.dto.User;

@Controller
public class UserController {

	// 1. 로그인 페이지 직접 URL 요청해서 응답 받을 수 있다. (사전 지식) 
	// 2. 로그인 페이지를 controller를 타서 응답 처리해 보자. 
	@GetMapping("/login-page")
	public String login() {
		return "login.html";
	}
	
	// MIME TYPE - form : x-www-form-urlencoded 
	// @RequestBody <-- application/json
	@PostMapping("/login-proc")
	public String loginProc(HttpServletRequest request,
							HttpServletResponse response, User user) {
		// 로직 : 세션 저장 후 myInfo 페이지 이동 처리 함 
		HttpSession session = request.getSession();
		System.out.println("user : " + user);
		session.setAttribute("user", user);
		//response.sendRedirect("/mypage/myinfo");
		return "redirect:/mypage/myinfo.html";
	}
	
	// myinfo 설계 
	// http://localhost:8080/mypage/myinfo <-- 설계 해야 인터 페이스 동작 됩
	@GetMapping("/mypage/myinfo")
	public String myInfo() {
		// 인증이 필요한 페이지로 만들기로 함
		return "mypage/myinfo.html";
	}
}

static/login.html 파일 생성

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>로그인 페이지 입니다.</h1>
	<form action="/login-proc" method="post">
		<input type="text" name="username" value="tenco">
		<br>
		<input type="password" name="password" value="1234">
		<br>
		<input type="submit" value="로그인처리">
	</form>
</body>
</html>

static/mypage/myinfo.html 파일 생성

여기 페이지는 인증된 사용자만 들어 올 수 있도록 설계

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>MyInfo 페이지 입니다</h1>
	<h2>여기는 인증된 사용자만 페이지를 볼 수 있도록 처리 할 예정</h2>
</body>
</html>

static/mypage/cart.html 파일 생성

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>cart.html 파일 입니다.</h1>
	<h2>여기에도 인증된 사용자만 들어 올수 있도록 코드 추가</h2>
</body>
</html>
package com.example.demo9.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import com.example.demo9.dto.Cart;
import com.example.demo9.dto.User;

@Controller
public class UserController {

	// 로그인 페이지 직접 URL 요청해서 응답 받을수 있다.
	// 로그인 페이지를 controller 를 타서 응답 처리해보자.
	@GetMapping("/login-page")
	public String login() {

		return "login.html";
	}

	@PostMapping("/login-proc")
	public String loginProc(HttpServletRequest request, HttpServletResponse response, User user) {
		// 로직 : 세션 저장후 myInfo 페이지 이동 처리함
		HttpSession session = request.getSession();
		System.out.println("user : " + user);
		session.setAttribute("user", user);
		return "redirect:/mypage/myinfo.html";
	}
	
	@PostMapping("/cart-proc")
	public String cartProc(HttpServletRequest request, HttpServletResponse response, Cart cart) {
		// 로직 : 세션 세션에 저장된 값을 한번 더 받아와서 인증 처리를 해준후 넘겨준다
		// 세션 값을 저장해두기때문에 한번더 넣을 필요없이 키값으로 저장되어있는 값을 불러와서 
		// 확인 후 넘겨준다
		HttpSession session = request.getSession();
		System.out.println("cart : " + cart);
		session.setAttribute("cart", cart);
		return "redirect:/mypage/cart.html";
	}
	
	// myinfo 설계
	// http://localhost:8080/mypage/myinfo <-- 설계 해야
	@GetMapping("/mypage/myinfo")
	public String myinfo() {
		// 인증이 필요한 페이지로 만들기로 함
		return "mypage/myinfo.html";
	}


}

spring boot 에서 제공하는 interceptor 를 활용하여 인증 처리 로직을 구현

HandlerInterceptor 구현한 AuthInterceptor 클래스 생성하기

package com.example.demo9.handler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

@Component // IoC 대상 
public class AuthInterceptor implements HandlerInterceptor {
	
	// myInfo 이동시 세션 여부를 확인 (controller 들어가 전에 가로채기) 
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		HttpSession session = request.getSession();
		// 사용자가 로그인을 하면 세션 메모리 영역에 user 키=값 구조로 저장 처리 할 예정
		Object user = session.getAttribute("user");
		System.out.println("preHandler 동작 확인 ");
		if(user == null) {
			response.sendRedirect("/login-page");
			return false; 
		} 
		return true;
	}
}

우리가 만든 AuthInterceptor 등록할 WebMvcConfig 클래스 생성하기

package com.example.demo9.handler;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
	
	@Autowired // DI 처리 
	private AuthInterceptor authInterceptor;
	
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// 야 authInterceptor 동작 시킬 때 모든 페이지를 
		// 너가 가로채면 무조건 리다이렉트 되잖아 !!!
		// 그게 아니라 내가 명시하는 요청 설계 주소에서만 동작 
		// 하도록 일 하겠니!!
		// http:localhost:8080/hello <-- 인터 셉터 동작 하지 않음 
		// http:localhost:8080/mypage/myinfo <-- 인터 셉터 동작 함 
		registry.addInterceptor(authInterceptor)
				.addPathPatterns("/mypage/**");
	}
}

 

'Spring boot' 카테고리의 다른 글

Spring boot - Interceptor - 1  (0) 2023.04.13
스프링 부트 JSP 연결  (0) 2023.04.13
spring boot execption(예외처리)  (0) 2023.04.13
Spring Boot Validation  (0) 2023.04.13
어노테이션 종류  (0) 2023.04.13

+ Recent posts