✅ 순서
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
어노테이션도 등록한다@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();
}
}
encode
와 matches
설정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";
}
}
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>