[Spring] MySQL을 이용한 Session 로그인 구현

우잼·2023년 9월 17일
1
post-thumbnail

1. 세션(Session)


  • 일정 시간동안 같은 사용자로부터 들어오는 일련의 요구를 하나의 상태로 보고 그 상태를 일정하게 유지시키는 기술
  • 쿠키는 사용자 정보를 컴퓨터 메모리에 저장, 세션은 서버에 저장
  • 기존의 쿠키는 위변조 및 도용 문제가 발생할 수 있기 때문에 클라이언트는 서버의 데이터를 요청할 수 있는 JESSIONID만 가지고 있고, 이 key 또한 유효시간을 짧게 설정하고 갱신을 반복하면 보안상으로 안전해짐

    http는 stateless이므로, 상태를 유지하지 않는다. 화면의 이동에 대한 값 유지가 필요한 경우가 많은데 http는 이를 지원하지 않는다. 이것을 가능하게 해주는것이 cookie와 session이다.

2. 구현


2.1. 개념

  • 로그인 성공 시 세션을 하나 생성
    • 세션의 Key 값은 보통 UUID로 설정 (UUID는 중복되지 않는 랜덤, 예측x 값)
    • Value 값에 사용자 정보를 넣음
  • Session은 서버측 Session 저장소에 보관
  • Key 값을 Cookie를 통해 사용자에게 전달
  • 서버는 사용자에게 쿠키를 통해 key를 받으면 해당 key로 서버의 세션 저장소에서 검색
  • 일치하는 세션의 value에 들어있는 사용자의 정보를 통대로 인증, 인가를 진행
  • 쿠키 로그인과는 다르게 Session의 key 값이 예측할 수 없기 때문에 다른 사용자인 것 처럼 요청을 보내는 것이 불가능하다는 장점이 있지만 사용자 수가 많아진다면 서버에 저장해야 할 session의 수가 많아진다는 단점이 존재
  • HttpSession 클래스를 사용하면 Session을 만들 수 있음

2.2. 세션 생성

  • HttpServletRequest 객체의 getSession 메소드를 사용하면 Session을 가져옴
  • getSession 메소드로 세션 객체를 생성
    • 파라미터 true: Session이 있으면 가져오고 없으면 생성해서 return, default = true
    • 파라미터 false: Session이 있으면 가져오고 없으면 null return
// Session이 있으면 가져오고 없으면 null return  
 HttpSession session = httpServletRequest.getSession(true)
  HttpSession session = httpServletRequest.getSession(false)
  • 생성된 Session에 key, value 설정
session.setAttribute("email"), email)
  • Session 유효 시간도 설정 가능
session.setMaxInactiveInterval(1800)

2.3. 세션 확인

  • getSession() 메소드를 사용해서 Session을 가져옴
///email은 가져오고 싶은 session의 key
session.getAttrivute("email")
  • @SetAttribute 어노테이션을 통해 Session의 값을 가져올 수 있음
 public String checkSession(@SessionAttribute(name="email", required = false) String email, HttpServletRequest request) {

       if(email == null) {
           return "Login please";
       }else {
           return email;
       }
    }

2.4. 세션 파기

  • invalidate() 메소드를 사용하여 binding된 세션 데이터 일괄 삭제
HttpSession session = request.getSession(false);
session.invalidate();
  • removeAttribute(key) 메소드를 사용하여 특정 키 값의 세션 데이터 삭제
session.removeAttribute("email");

3. Spring에서 Session


3.1. Session 저장은 어디에?

  • Cache 처럼 Spring에서 지원해주는 기본 SessionStorage는 없음
    대체 그럼 어디에 저장되는거지..??

    SpringBoot의 was의 기본값은 Tomcat이다. 이 Tomcat의 "SESSION.ser" 파일에 session의 상태가 저장된다.

  • 스프링 세션은 JDBC, MongoDB, Redis 등을 사용하여 데이터를 유지가능

3.2 JDBC - MySQL

  • 개인적으로 나는 Session Storage로 MySQL을 선택했다. (이유는 그냥 MySQL을 연동한김에..)
    • 먼저 MySQL과 연동한 뒤 spring-session-jdbc을 종속성에 추가해줘야 한다.
      mysql_session
    • MySQL까지 연동하고 server를 실행시키면 다음과 같이 SPRING_SESSION과 SPRING_SESSION_ATTRUBUTES가 자동으로 생성된다.

❗️ 처음에 session 저장소를 이용하여 postman을 통해 여러 user가 다른 이메일 계정으로 로그인 하였을 때 각 user마다 session을 db에 저장하고자 하였는데 계속 다른 계정으로 session을 생성해도 기존의 session에서 update가 되었다. 뭐가 문제인지 찾을려고 엄청 검색해도 알 수가 없어서.. 포기할려던 참에....
postman header 구성을 살펴보았더니 sessionId가 바뀌지 않고 계속 똑같은걸 보게 되었다. 그래서 검색해보니 postman에서 sessionId를 바꾸기 위해서는 수동으로 Cookie를 수정해줘야 했던거다..... ㅠㅠㅠ 그래서 수동으로 sessionId를 수정하니 내가 원했던대로 다양한 유저가 로그인 했을때 각 user의 session이 저장되었다 완성되었다..

4. 문제점


  • 저장 공간의 용량

    • 세션은 서버의 메모리 내부에 저장이 되므로 유저가 수천명인 대형 서비스에서는 세션의 양이 많아지는 만큼 메모리에 부하가 올 수 있음
  • 확장성의 문제

    • 서비스의 규모가 커져서 서버를 여러대로 확장 및 분산해야 한다면 세션을 분산시키는 기술을 따로 설계해야 함

이를 해결하기 위해 JWT 라는 로그인 방식을 도입

5. Reference


[Spring Boot] Session을 사용한 로그인 구현

[Spring Boot] Session과 Cache의 기본 저장소 !

[Spring] 스프링 상태유지 기술(쿠키, 세션)

Session 기반 인증의 문제점

profile
나는 재민

0개의 댓글