본문 바로가기

Spring

Session에 값을 추가하고 interceptor로 검사해서 통과한 사용자만 페이지에 접속할 수 있도록

상황

  1. 각각의 게시판이 존재한다. (1번게시판, 2번게시판…)
  2. 각각의 게시판은 비밀번호를 가지고 있다.
  3. 게시판을 비밀번호치고 들어가면 세션에 비밀번호를 저장한다.
  4. 한 번 들어간 게시판은 다시 비밀번호를 치고 들어가지 않아도 된다.
  5. 로그아웃 시 세션을 삭제
//BoardController

@PostMapping("/password")
    public String boardPassword(@Valid CapsuleDto capsuleDto, BindingResult bindingResult, @PathVariable Long capsuleId, Model model, HttpServletRequest request) {
       
        HttpSession session = request.getSession();
        //현재 세션의 정보
      
        session.setAttribute("capsule" + capsuleId + "access", capsuleDto.getCapsulePassword());
        //세션에 캡슐에 따른 비밀번호키 추가
        

        if (!encoder.matches(session.getAttribute("capsule" + capsuleId + "access").toString(),capsule.getCapsulePassWord())) {
            session.removeAttribute("capsule" + capsuleId + "access");
            // 비밀번호와 일치하지않으면 세션에서 값 삭제
            bindingResult.rejectValue("capsulePassword", "passwordInCorrect",
                    "비밀번호가 일치하지 않습니다.");
            return "board/boardPassword";
            // 비밀번호와 일치하지 않으면 경고 문구를 띄우고 새로고침
        }
        return "redirect:/%d/board/list".formatted(capsuleId);
				//일치하면 게시판 리스트 페이지로 이동
    }
//SecurityConfig

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig implements WebMvcConfigurer {
//interceptor를 사용하기 위해서는 WebMvcConfigurer를 받아야 한다.
    private final Interceptor interceptor; 

  @Override
    public void addInterceptors(InterceptorRegistry registry){
        registry.addInterceptor(interceptor) //interceptor 등록
                .addPathPatterns("/*/board/list"); //interceptor 할 페이지 패턴
    }
//Interceptor

@Slf4j
@Component
public class Interceptor implements HandlerInterceptor {

@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        HttpSession session = request.getSession();
        String capsuleId = request.getRequestURI().split("/")[1];
        try {
            String confirm = session.getAttribute("capsule" + capsuleId + "access").toString();
            // 해당 게시판에 대한 세션이 없으면 catch문으로 넘어감
        }catch(NullPointerException e){
            log.info("비밀번호가 없음");
            response.sendRedirect("/%s/board/password".formatted(capsuleId));
            //세션에 비밀번호가 없으면 비밀번호 입력 페이지로 이동.
            return false;
        }
        log.info("비밀번호가 있음");
        return true;
    }
}