세션(Session)이란?

JangUT·2025년 2월 26일

📌세션(Session)


  • 세션(Session) 은 클라이언트와 서버 간의 연결을 유지하고, 특정 사용자에 대한 상태를 저장하는 기술이다.
  • 웹 애플리케이션에서 사용자가 로그인 또는 특정 작업을 수행할 때, 서버가 사용자의 정보를 유지하기 위해 세션을 활용한다.

📌세션(Session) 의 동작 방식


세션 생성

  • 사용자가 로그인하면 서버는 고유한 세션 ID를 생성
  • 세션 ID는 UUID와 같이 예측할 수 없는 값으로 생성
  • 서버는 이 세션ID를 키(key)로 하고, 사용자 정보를 값(value)으로 하는 세션을 저장소에 저장

세션 유지

  • 서버는 생성된 세션ID를 클라이언트에게 쿠기를 통해 전달.
  • 클라이언트는 이후 요청 시마다 이 쿠키(세션ID)를 서버에 전송.

세션 확인

  • 서버는 요청에서 전달된 세션ID를 확인하고, 세션 저장소에서 해당 세션을 조회
  • 세션이 유효하면 사용자 정보를 가져와 인증 및 인가를 처리

세션 종료

  • 로그아웃하거나 세션이 만료되면 서버는 해당 세션을 삭제
  • 클라이언트의 쿠키에 저장된 세션ID는 더 이상 유효하지 않음

📌세션의 원리 이해

  • 클라이언트는 서버로부터 받은 세션ID를 쿠키로 저장
  • 서버는 클라이언트가 전송한 세션ID를 이용하여 저장소에서 세션을 조회합니다.
    보안 주의 사항
  • 세션 ID 보안 강화
    • 예측 불가능한 난수를 사용하여 생성 (예 : UUID)
    • 세션 ID의 재사용 방지 (로그인 시 세션ID 변경)
  • 네트워크 보안
    • HTTPS를 사용하여 세션ID 탈취 방지
    • SecureHttpOnly 속성을 설정하여 쿠기 보안 강화
  • 세션 하이재킹 방지
    • IP 및 User-Agent 검증을 통해 의심스러운 세션 차단
    • 일정 시간 후 세션 자동 만료 설정
    • 로그인 시 기존 세션 무효화 처리

※🌈 세션 하이재킹(Session Hijacking) 이란
- 공격자가 사용자의 세션ID(Session ID)를 가로채어 해당 사용자의 세션을 탈취하는 공격 기법입니다.
- 이를 통해서 공격자는 정상 사용자인 것처럼 서버에 접근하여 정보를 탈취하고, 불법적인 요청을 수행해 악의적인 행위를 할 수 있음

📌세션 생성과 관리

  • 세션 생성 : HttpServletRequest 에 메서드 getSession(true)이용해 생성
    • 세션이 있으면 반환하고, 없으면 새로 생성
  • 세션 가져오기 : HttpServletRequest 에 메서드 getSession(false)이용해 가져옴
    • 세션이 있으면 반환하고, 없으면 null을 반환합니다.
  • 세션 값 저장 : HttpSession 에 메서드 session.setAttribute("key", value); 형태로 저장
  • 세션에서 값 가져오기 : HttpSession 에 메서드 session.getAttribute("key");
  • 세션 만료 시간 설정 : HttpSession 에 메서드 session.setMaxInactiveInterval(1800); (단위:초)

간단한 예제를 코드로 구현한다면

User Entity


@Entity
@Table(name = "users")
public class User {

	@Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column
    private String email;
    
    @Column
    private String password;
   
    // 기본 생성자
	public User() {}   
    
    // getters and setters
}

LoginRequestDto


@Getter
public class LoginRequsetDto {

	private final String email;
    
    private final String password;
    
}

UserController

	
@RestController
@RequestMapping("/users")
public class UserController {

	private static final String USER_ID = "userId";

	@PostMapping("/session-login")
    public ResponseEntity<String> login(
    	@RequestBody LoginRequestDto request,
        HttpServletRequest httpServletRequest
   ) {
   \
   		User user = userService.login(request);
   		// 세션 생성
        HttpSession session = httpServletRequest.getSession(true);
        
        // 세션에 "key" 값을 userId 설정 "value" 값을 user.getId() 로 설정
        session.setAttribute(USER_ID, user.getId());
        
        // 세션 만료시간 30분으로 설정
        session.setMaxInactiveInterval(1800); // 30분
        
        return ResponseEntity.status(HttpStatus.CREATE).body("로그인 성공 및 세션 생성");
    }
    
    
    @GetMapping("/session-login")
    public ResponseEntity<String> login(HttpServletRequest httpServletRequest) {
    	// 세션이 존재하면 세션값 반환, 세션 없을 경우 `null` 반환
    	HttpSession session = httpServletRequest.getSession(false);
        
        // session 이 null 경우
        if (session == null) {
        	return "세션이 없습니다."
        }
        
        // 현재 "key" 값(USER_ID)에 해당하는 value를 가져옴
        return session.getAttribute(USER_ID);
    

Session을 이용하여 클라이언트와 서버간에 상태를 유지하는 방법에 대해서 알아보았습니다.

잘못된 부분에 대해 피드백을 주신다면 감사하겠습니다.

profile
평범한 개발자

0개의 댓글