Spring Security 없이 로그인을 하는 방법 (Session)

2025. 5. 7. 16:08·SpringBoot

 

최근 개인 프로젝트를 진행하며 로그인 관련하여 공부했던 부분에 대해서 작성해보려고 합니다.
spring security는 이전 회사에 있을 때 간단하게 사용했던 경험이 있습니다. 그런데 사용하다 보니 이렇게 작은 볼륨의 프로젝트 (사실상 로그인 관련 로직은 회원가입, 로그인, 로그아웃, 계정삭제, 게시판과의 연동) 정도밖에 없는데 굳이 Spring security를 사용해야 하는지에 대한 의문이 생겼습니다. 

또한 진행하고 있는 부트캠프의 튜터님도 굳이 써야하는지에 대한 생각을 해보고 그전에 로그인 관련 지식을 완벽히 쌓는것이 중요하다라고 조언을 해주셨기에 그 부분에 대해서도 고민을 하다보니 내가 로그인을 그냥 "구현"만 하려고 문서가 많은 Spring security를 사용하려 했었다 라는 생각이 들었습니다.

따라서 이번에 저는 Session을 이용해서 진행하고 있기에 기초적인 세션 및 Http에 대한 지식과 마지막으로 어떻게 구현을 했는지에 대해서 살펴보도록 하겠습니다.

특정 기술을 사용해서 프로젝트를 하는데 그 개념에 대해서 완벽히 알아야 한다고 생각합니다.
session에 대한 개념과 사용의미를 알기 위해서는 Http 에 대해서 이해를 해야 합니다.

**Http 프로토콜**
HTTP(HyperText Transfer Protocol)는 웹에서 데이터를 주고받을 때 사용하는 프로토콜입니다.
중요한 특징으로는 Stateless한 프로토콜이라는 점입니다. 이전 요청에 대한 기억이 없기에 Request, Response 모두 1회성입니다.

**Session**
그렇다면 세션이 필요한 이유가 보입니다. 웹이 요청/응답이 1회성이기 때문에 사용자를 구분하기 위해서 필요한 것이 큰 이유입니다. 세션의 개념은 사용자와 서버 간의 특정 기간 동안 유지되는 상태 또는 연결 정보이기 때문입니다. 동작순서를 확인해보겠습니다.
1. 사용자 로그인
2. 서버는 SessionId 생성
3. SessionId 쿠키를 통해 클라이언트에게 전송
4. 이후 클라이언트는 자동으로 요청마다 SessionId가 들어있는 쿠키를 전송
5. 서버에 저장해놓은 세션을 통해서 사용자 구분하여 요청 처리

물론 세션을 사용한 인증방식은 문제점이라고 볼만한 부분이 있습니다. 기본적으로 단일도메인에서만 쿠키가 전송된다는 점. 사실 기업에서 가상화환경에서 만약 백/프론트 환경이 동일하게 되어있다 혹은 Jsp를 사용한다는 등 다양한 상황이 있기에 쓸 수 있지만 보안정책이나 Cors에 따라서 막힐 때가 많다고 합니다.

물론 지금 저는 개인 프로젝트이기에 단일 도메인이라 세션을 사용했습니다.

그렇다면 이제 스프링 시큐리티를 사용하는 이유를 알아보겠습니다. 정확히 왜 사용하는지에 대해 알아야 사용할 때 명확한 상황에서의 필요성을 알고 그 차이를 알 수 있기 때문입니다.

JWT TOKEN이든 SESSION이든 구현할 수 있는데 왜 쓸까요?

우선 직접 사용을 해보며 느낀바는 패스워드 암호화 입니다. 스프링 시큐리티는 간단하게 패스워드 암호화를 도와주는 기능이 있습니다.
두번째는 권한에 대한 허용입니다. 직접 인증 로직을 작성하게 된다면 컨트롤러마다 그에 따른 조건문을 작성하여 활용해야 합니다. 물론 인터셉터를 만들 수도 있습니다.
또한 느낀 바로는 공부해야할 부분이 꽤나 많다고 생각됩니다. 오래되고 수많은 업데이트들이 진행되었기 때문에 학습량이 꽤나 많습니다. 다음 개인프로젝트를 할 때는 공부하며 제대로 사용해볼 예정입니다.
결과적으로는 편의성 부분에서 자신이 공부가 되었다면 편리하게 사용할 수 있다! 라는 점이 가장 큰 메리트라고 생각이 듭니다.

그렇다면 작성한 코드를 보겠습니다. 저는 서버의 메모리를 통해서 저장소를 구현했습니다. 

@Component
public class SessionStorage {

  private final Map<String, HttpSession> sessions = new HashMap<>();

  public void addSession(String sessionId, HttpSession session) {
    sessions.put(sessionId, session);
  }

  public void deleteSession(String sessionId) {
    sessions.remove(sessionId);
  }

  public String getIdBySessionId(String sessionId) {
    return (String) sessions.get(sessionId).getAttribute("id");
  }

  public boolean doesNotContains(String sessionId) {
    return !sessions.containsKey(sessionId);
  }
}


이를 클래스에서 관리하여 로그인을 하게 되면 sessionStorage Map의 Key 값에는 HttpSession의 JSESSIONID, HttpSession에는 로그인할 때 만든 session이 들어갑니다. 또한 내부 메서드의 명칭의 의미처럼 추가, 삭제 등 기능을 구현했습니다.

물론 저는 라이브러리를 통해서 관련 로직을 작성한 것이 아니기 때문에 자동적으로 로그인이 되어 있는지를 체크할 코드가 필요합니다. 인터셉터를 구현해도 되고 다양한 방법이 있겠지만 우선 직관적으로 코드를 작성했습니다.

@Component
public class SessionUtil {

  private final SessionStorage sessionStorage;
  private final UserRepository userRepository;

  public SessionUtil(SessionStorage sessionStorage, UserRepository userRepository) {
    this.sessionStorage = sessionStorage;
    this.userRepository = userRepository;
  }

  public boolean checkSession(HttpServletRequest req) throws SecurityException {
    String sessionId = Arrays.stream(req.getCookies())
        .filter(cookie -> cookie.getName().equals("JSESSIONID"))
        .map(Cookie::getValue)
        .findAny()
        .orElseThrow(() -> new SecurityException("세션 정보 없음"));

    if (sessionStorage.doesNotContains(sessionId)) {
      throw new SecurityException("포함하지 않는 세션입니다.");
    }

    int id = Integer.parseInt(sessionStorage.getIdBySessionId(sessionId));
    Optional<User> user = userRepository.findById(id);

    if (!user.isPresent()) {
      throw new SecurityException("유저 이메일이 올바르지 않은 세션입니다.");
    }

    return true;
  }
}


이와 같은 유틸 클래스를 만들어서 내부 메서드 checkSession을 통해서 JSESSIONID가 존재하는지 확인을 하고 존재한다면 그 값을 통해서 DB의 사용자가 존재하는지를 확인하는 메서드입니다. 이를 로그인이 필요한 로직에서 확인을 검증을 한 후 본 기능을 구현하면 될 것입니다.

 

컨트롤러단에서 매개변수로 HttpServletRequest를 매개변수로 받아서 검증을 하고 글 작성 로직이라면 글을 작성해주면 될 것입니다.

 

 

 

 

 

 

'SpringBoot' 카테고리의 다른 글

SpringBoot 대용량 데이터 조회 (Index)  (1) 2025.07.03
AOP 탐구  (0) 2025.07.01
JPA 영속성 파헤치기  (0) 2025.06.28
SpringEvent / EDA  (2) 2025.06.24
Spring 예외처리 (@ExceptionHandler, @ControllerAdvice)  (0) 2025.05.12
'SpringBoot' 카테고리의 다른 글
  • AOP 탐구
  • JPA 영속성 파헤치기
  • SpringEvent / EDA
  • Spring 예외처리 (@ExceptionHandler, @ControllerAdvice)
vanc
vanc
공부 기록 블로그입니다.
  • vanc
    Vanc
    vanc
  • 전체
    오늘
    어제
    • 분류 전체보기 (29) N
      • Project (0)
      • SpringBoot (8)
      • Java (0)
      • 백준 (0)
      • 부트캠프 (0)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Transactional
    spring data elasticsearch 8
    @ExceptionHandler
    정합성
    @entitygraph
    fetch join
    일정관리
    REQUIRES_NEW
    @Enumerated
    @ControllerAdvice
    N+1
    @ResponseStatus
    db
    @converter
    JPA
    jdbc
    동시성이슈
    @BatchSize
    springboot
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
vanc
Spring Security 없이 로그인을 하는 방법 (Session)
상단으로

티스토리툴바