Springboot 암호화 처리 및 필터 적용 + 공통 메시지 페이지

최주영·2024년 3월 7일
0

springboot

목록 보기
12/14

✅ 순서

  • pom.xml에 spring-boot-starter-security 라이브러리를 추가해준다
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>

  • Filter 인터페이스를 구현할 클래스 생성함
// package com.joo.usedmarket.filter;
public class LoginFilter implements Filter{

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
	    // HttpServletRequest 클래스의 메소드를 사용하기 위해서 강제 형변환
		HttpServletRequest httpRequest = (HttpServletRequest)request;
		String requestURI = httpRequest.getRequestURI();
		HttpServletResponse httpResponse = (HttpServletResponse)response;
		
		HttpSession session = ((HttpServletRequest)request).getSession(false); 
		
		if(session.getAttribute("loginUser") == null) { // 현재 로그인한 세션 갖고있으면

			httpResponse.sendRedirect("/user/loginView?redirectURL="+requestURI);
			
			return;
		}

		chain.doFilter(request, response);
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		Filter.super.init(filterConfig);
	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		Filter.super.destroy();
	}
	
}

  • FilterRegistrationBean 객체를 반환하는 클래스 생성
// package com.joo.usedmarket.config;
@Configuration
public class WebConfig {
	@Bean
	public FilterRegistrationBean loginFilter() {
		FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();
		filterRegistrationBean.setFilter(new LoginFilter()); // 만든 필터 클래스 생성
		filterRegistrationBean.setOrder(1);
		filterRegistrationBean.addUrlPatterns("/product/productRegistView");
		
		return filterRegistrationBean;
	}
}

  • @EnableWebSecurity 어노테이션을 통해 암호화 적용
  • 클래스를 하나 만들어서 스프링에 등록해야하기 때문에 @Configuration 어노테이션도 등록한다
  • PasswordEncoder 객체타입을 리턴받는 메소드를 생성해서 등록해야하기 때문에 @Bean 등록
// com.joo.usedmarket.config.MyWebMvcConfiguration
package com.joo.usedmarket.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class MyWebMvcConfiguration {

	@Bean
	public PasswordEncoder getPasswordEncoder() {
		return new BCryptPasswordEncoder();
	}

	 @Bean 
	  public SecurityFilterChain authenticationPath(HttpSecurity http) throws Exception{
	  
	  return http.csrf(csrf -> csrf.disable()) // 빌더패턴방식으로 메소드를 하나씩 적기
	  .formLogin(form->form // formLogin -> 로그인에 대한 정보 
			  		.disable()).build();
	 }  
} 

  • 컨트롤러에서 encodematches 설정
    matches : 원본값과 암호화된 값이 일치한지 boolean 값으로 반환
    encode : 원본값을 암호화하는 메서드
// com.joo.usedmarket.user.controller.UserController
package com.joo.usedmarket.user.controller;

import com.joo.usedmarket.user.dto.UserDto;
import com.joo.usedmarket.user.service.UserService;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;

@Controller
@Slf4j
@RequestMapping("/user")
public class UserController {
	
	private UserService service;
	private PasswordEncoder passwordEncoder;
	
	public UserController(UserService service,PasswordEncoder passwordEncoder) {
		this.service = service;
		this.passwordEncoder = passwordEncoder;
	}
	
	@GetMapping("/loginView") // 로그인화면이동
	public String loginView() {
		return "login/loginView";
	}
	
	@PostMapping("/login") // 로그인
	public String login(@ModelAttribute UserDto user,
			/*@RequestParam("userId") String userId, @RequestParam("password") String password,*/
			HttpServletRequest request, Model model) {
		// 검증 encode() , 비교 matches()
		 UserDto loginUser = service.selectByUserId(user); // 로그인한 아이디가 일치한 유저객체 조회
			
		 if(loginUser == null) { // 로그인한 아이디가없으면
			 return "redirect:/user/loginView";
		 }else {
			 if(passwordEncoder.matches(user.getPassword(),loginUser.getPassword())) { 
             // 찾은 아이디의 암호화된 비밀번호와 사용자가 입력한 패스워드가 일치하면
				 HttpSession session = request.getSession();
				 session.setAttribute("loginUser", loginUser); // 세션값 저장
				 return "redirect:/";
			 }
		 }
		 return "redirect:/user/loginView";
	}
		
	
	@GetMapping("/logout")
	public String logout(HttpServletRequest request) {
		HttpSession session = request.getSession(false); // false로해야 기존세션이없어도 생성 x
		
		System.out.println(session.getAttribute("loginUser"));
		
		if(session != null) {
			session.invalidate(); // 세션삭제
		}
		return "redirect:/";
	}
	
	
	@GetMapping("/enrollUserView")
	public String enrollUserView() {
		return "login/enrollUserView";
	}
	
	@PostMapping("/enrollUser")
	public String enrollUser(@ModelAttribute UserDto user, Model model) {
		
		String msg="";
		String loc="";
		
		user.setPassword(passwordEncoder.encode(user.getPassword())); // 암호화시켜서 저장
		
		if(service.enrollUser(user) >= 1) {
			msg = "회원가입 성공!";
			loc = "/";
		}else {
			msg = "오류 발생 (회원가입 실패)";
			loc = "/user/enrollUserView";
		}
		
		model.addAttribute("msg",msg);
		model.addAttribute("loc",loc);
		
		return "common/msg";
	}
}

  • msg.jsp에서 메시지 출력하고 다시 redirect
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="path" value="${pageContext.request.contextPath}"/>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>시스템메세지</title>
</head>

<body>
	<script>
		// alert 뒤에 "" 없이 값만넣으면 변수로 인식됨
		alert("${msg}");
		location.replace("${path}${loc}");
	</script>
</body>
</html>
profile
우측 상단 햇님모양 클릭하셔서 무조건 야간모드로 봐주세요!!

0개의 댓글