웹 소켓이란 ?

HTML5 에서 정의한 프로토콜이다. 클라이언트와 서버 간의 양방향 통신을 가능하게 한다.

HTTP 프로토콜과 달리, 웹 소켓은 지속적인 연결을 유지하면서 실시간으로 데이터를 주고받을

수 있다. 이는 채팅, 실시간 알림과 같은 애플리케이션에서 사용된다.

 

웹 소켓의 동작 방식

1. 핸드셰이크(Handshake)

  • 웹 소켓 통신은 일반적인 HTTP 요청으로 시작한다. 클라이언트는 웹 소켓 연결을 시작하기
    위해 서버에 HTTP 요청을 보낸다.
  • 서버는 요청을 수락하고, HTTP 응답을 보내면서 프로토콜을 웹 소켓으로 업그레이드한다.

2. 연결 유지

  • 핸드셰이크가 완료되면, 클라이언트와 서버 간의 연결은 지속적으로 유지된다.
  • 이 연결을 통해 양방향 통신이 가능하며, 클라이언트와 서버는 언제든지 메시지를 주고받을
    수 있다.

3. 데이터 전송

  • 클라이언트와 서버는 웹 소켓 프레임을 통해 데이터를 전송한다. 프레임은 작은 단위의 데이터 조각이며,
    여러 프레임이 모여 하나의 메시지를 구성할 수 있다.
  • 데이터는 텍스트 또는 바이너리 형식으로 전송될 수 있다.
STOPM 란 ?

- STOMP (Simple (or Streming) Text Oriented Messaging Protocol)는 메시징 시스템에서 사용하는 프로토콜로,

클라이언트와 서버 간의 메시지 전송을 위해 설계되었다. 주로 웹 소켓[각주:1]과 함께 사용되어 실시간 통신을 가능하게 한다.

STOMP는 텍스트 기반 프로토콜로, 메시지를 전송하기 위한 간단한 명령 세트를 제공한다.


STOMP의 주요 개념 및 동작 방식

 

1. Connect and Disconnect (연결 및 연결 해제)

  • 클라이언트는 서버에 연결하기 위해 'CONNECT' 프레임을 전송
  • 서버는 연결이 수락되면 'CONNECTED' 프레임을 응답
  • 연결 해제는 'DISCONNECT' 프레임을 사용

2. Send (메시지 전송)

  • 클라이언트는 서버로 메시지를 보내기 위해 'SEND' 프레임을 사용
  • 메시지는 특정 목적지(destination)를 가지며, 이 목적지는 구독자가 메시지를 수신할 때 사용된다.

3. Subscribe and Unsubscribe (구독 및 구독 취소)

  • 클라이언트는 특정 목적지의 메시지를 수신하기 위해 'SUBSCRIBE' 프레임을 전송
  • 구독을 취소은 'UNSUBSCRIBE' 프레임 사용

4. Message (메시지)

  • 서버는 클라이언트에게 메시지를 전송할 때 'MESSAGE' 프레임 사용
  • 'MESSAGE' 프레임은 클라이언트가 구독한 목적지로부터의 메시지를 포함

5. Acknowledge and Nacknoewledge (확인 및 비확인)

  • 클라이언트는 메시지를 성공적으로 처리했음을 나타내기 위해 'ACK' 프레임을 전송할 수 있다.
  • 메시지를 처리할 수 없을 경우 'NACK' (Negative Acknowledgement)프레임을 전송할 수 있다.

STOMP 프레임 구조

 

  • COMMAND : 프레임의 종류를 나타낸다. ('CONNECT', 'SEND', 'SUBSCRIBE' 등)
  • Headers : 명령과 관련된 추가 정보를 제공한다. (각 헤더는 'key:value' 형식으로 작성)
  • Body : 메시지의 내용이 포함 (빈 줄 다음에 위치하며, '@' 문자가 프레임의 끝을 나타낸다)

 


STOMP 동작 예시

1. 클라이언트가 서버에 연결                         2. 서버가 연결 수락                        3. 클라이언트가 특정 목적지 구독 


                          4. 서버가 클라이언트에게 메시지 전송                           5. 클라이언트가 서버로 메시지 전송

  1. 웹 브라우저와 웹 서버 간의 양방향 실시간 통신을 가능하게 하는 기술 [본문으로]


- JWT(JSON Web Token)는 정보를 안전하게 전송하기 위한 웹 표준으로 클라이언트와 서버 간의 인증과 정보 교류를 위해 사용된다. JWT는 JSON 형식으로 되어 있으며, 암호화된 토큰으로서 클레임(Claim)이라는 속성들을 포함하고 있다.

 

JWT의 세가지 구성 요소

 


1. Header, JWT의 종류와 사용하는 알고리즘에 대한 정보를 담고 있다.

 


 

 

2. Payload, 실제로 전송할 클레임(Claim) 정보를 포함한다.

클레임에는 사용자의 정보나 추가적인 메타데이터를 포함한다.

 


3. Signature, Header와 Payload의 내용을 Base64로 인코딩한 후,

비밀 키를 사용하여 서명된 부분으로 이를 통해 JWT의 무결성을 검증할 수 있다.


JWT의 사용

  • 인증(Authentication) : 사용자가 로그인할 때 JWT를 발급하여 클라이언트에게 전달한다. 
    클라이언트는 로그인 이후 요청에 해당 JWT를 포함시켜 사용자(본인)을 인증한다.
  • 정보 교류(information Exchage) : 클라이언트와 서버 간의 안전하게 정보를 교환하는 데 사용된다.
    JWT를 사용하면 HTTP 요청 헤더[각주:1]나 URL 파라미터에 포함해 사용할 수 있다.
  • Stateless 서비스 : JWT는 서버 측에서 세션 상태를 유지하지 ㅇ낳고도 인증을 처리할 수 있어
    stateless한 서비스 설계에 유리하다.
  1. URL 파라미터 보다 JWT의 노출없이 전송할 수 있는 HTTP 헤더를 통한 요청이 보통 사용된다 (Autorization: Bearer JWT 형식) [본문으로]

로컬 환경에서의 Redis 설정 방법 익히기


로컬환경에서의 기본적인 RedisConfig 설정방법

 

 

의존성 추가


RedisRepositorytConfig 설정


 

 

 

RedisProperties

- Spring boot에서 Redis 관련 설정을 담는 클래스이다.

 

spring.data.redis

- prefix 값으로 해당 위치에 redis 관련 값 즉 host, port 및 password 등을 넣게 되면 해당 객체가 생성될때 명시해준 값으로 오버라이딩돼 들어가게 된다. 

 

(로컬환경에서의 테스트때는 RedisProperties에 host로 localhost와 기본 Redis port인 6379가 들어가있기 때문에 application.properties 또는 yml에 별도의 설정을 하지 않아도 작동한다)

 

 


RedisConnectionFactory

- Redis와의 연결을 관리하기 위한

인터페이스로 Redis 클라이언트 구현체인 Lettuce나 Jedis 등을 이용해 Redis 서버와의 연결을 설정하고 제어한다.

 

- 대표 메서드로 getConnection 메서드는 Redis 서버와의 연결을 생성하고 반환한다.



LettuceConnectionFactory

- Redis 서버와의 연결을 관리하기 위한 구체적인 구현체 중 하나이다.

현재는 host와 port만 파라미터로 넣어 구현체로써 사용하고 있지만,

@Bean
public LettuceConnectionFactory redisConnectionFactory() {
    RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration(redisHost, redisPort);
    redisConfig.setPassword(redisPassword);
    return new LettuceConnectionFactory(redisConfig);

이 처럼 RedisStandaloneConfiguration 을 이용해 password도 적용시켜 사용하는 방법이 존재한다.

'Java > Spring' 카테고리의 다른 글

[Spring Boot] STOPM란  (0) 2024.06.18
[Security] JWT란 ?  (0) 2024.06.18
accessToken 재발행 오류 처리(Filter 내에서의 오류 처리)  (0) 2024.04.19
RedisUtil (get, set 설정)  (0) 2024.04.16
RedisRepositoryConfig 설정  (0) 2024.04.16
  • refreshToken을 이용해 accessToken을 발행하는 로직을 구현 하던 도중..

서블릿에서의 에러가 발생

  • JwtAuthenticationFilter의 doFilterInternal 메서드 내부의 로직 때문에 생긴 에러이다.
    • doFilterInternal 로직 중 accessToken을 확인해 만료가 됐다면 refreshToken 메서드(서비스)로 연결이 된다.
    • 해당 서비스단 내부에서 새 토큰의 발행을 돕고, 그때 refreshToken 역시 만료가 됐다면 커스텀익셉션인 UserException을 발생시켜 GlobalExceptionHandler를 통해 처리가 되는 로직이다.
    • 그 과정에서 위의 문제가 발생했다.

문제가 발생하는 로직

  • 이유는 ?
    • 기존의 GlobalExceptionHandler로 처리 되던 에러들은 doFilterIntenal을 벗어나 로직상에서 문제가 발생 됐기에 처리가 가능했다.
    • 하지만 refreshToken 서비스는 doFilterIntenal 내부의 로직이기에 GlobalExceptionHandler로 연결 되지 못하고 예기치 못한 에러(서블릿단에서의 에러)로 연결 됐던 것

수정 후의 로직

  • try / catch를 이용해 서비스단에서 발생 시킨 UserException를 Filter 내부에서 직접 처리 해준다.
    • response를 새로 생성해 status 및 body를 생성해 내보낸다.
    • 마지막 return을 붙이지 않으면 지정해줬던 UserException이 아닌 403 Fobidden 상태를 발생시킨다.
      • return으로 현재의 로직 (response를 새로 만드는 것 까지) 을 끝내지 않으면 기존의 로직 (권한을 만들어내지 못한 상태로 진행) 이 진행 되어 결국 권한이 필요했던 요청에 권한이 없는 상태로 응답을 하기 때문에 UserException 을 발생시키지 않고 403 에러 메시지가 발생 되는 것.

 

나중에 내가 기억하기 위해 서비스단도 적어놓자.

'Java > Spring' 카테고리의 다른 글

[Security] JWT란 ?  (0) 2024.06.18
Redis Config 설정 (로컬환경에서의 설정 방법)  (0) 2024.06.17
RedisUtil (get, set 설정)  (0) 2024.04.16
RedisRepositoryConfig 설정  (0) 2024.04.16
PasswordEncoder 알고리즘 이모저모  (0) 2024.04.15

  • RedisTemplate<String, String> redisTemplage;
    • Redis와 통신하기 위한 Spring Date Redis의 Redis Template
  • setValues(key, value, duration)
    • redis에 저장될 키와 밸류 및 Duration 객체를 저장
  • getValues(key)
    • key를 통해 value를 가져옴

+ Recent posts