인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

hxcva1님의 프로필 이미지

작성한 질문수

웹소켓/STOMP 채팅서비스(spring, vue, redis)

stomp jwt인증 처리

jwt 인증 질문입니다.

작성

·

72

0

현재 connect 할때 토큰이 올바른지 확인하는데

이후 메세지를 저장할때 보낸 유저를 판단할때 이메일 정보를 이용해 보낸사람의 이메일로 유저를 찾는데 이경우 잘못될 가능성이 높을것 같아 처음 connection을 할때 저장해 두고 이걸 이용해서 보낸 유저를 구분하고 싶은데 어떻게 하는게 좋을까요?

답변 2

0

bradkim님의 프로필 이미지
bradkim
지식공유자

좋은 지적 감사합니다. sender를 조작해버릴수가 있겠네요.

 

먼저, connect시점에 Authentication객체를 만들어서 accessor에 setting을 해줘야 할것 같습니다.

예시)accessor.setUser(authentication);

 

이렇게 accessor에 담게 되면, 웹소켓연결 세션에 authentication객체를 담았다고 보시면 될것 같습니다.

 

그 이후에 websocket controller에서 Pricipal객체를 메서드에서 주입받아서 사용가능합니다.

 

예시)

@MessageMapping("/{roomId}") public void sendMessage(@DestinationVariable Long roomId, ChatMessageReq message, Principal principal) {

 

이때 주입되는 Pricipa객체에는 Authentication객체를 만들떄 들어간 email이 들어 있을것이므로, messageDto에는 이제 email을 넘겨받을필요가 없게 될것 같습니다.

hxcva1님의 프로필 이미지
hxcva1
질문자

답변 정말 감사합니다! 혹시 채팅창 프론트 부분에서도 sender를 구분해야 할때도 현재 방식의 경우 외의 좀더 안정적인 방법이 있을까요?

bradkim님의 프로필 이미지
bradkim
지식공유자

프론트창에서는 서버에서 준 dto를 기반으로 sender를 구분하니까, 현재 방식이 문제는 없어 보입니다.

hxcva1님의 프로필 이미지
hxcva1
질문자

현재의 경우 사용자가 로그인 시에 저장해둔 로컬스트리지에 저장한 값을 이용해 프론트에서

sender를 구분하는데 사용자가 이 값을 변경할수 있기 때문에 문제가 되지 않을까요?

bradkim님의 프로필 이미지
bradkim
지식공유자

음.. 근데 그 부분은 프론트에서 굳이 조작할필요도 없고, 조작해도 의미가 없지 않을까요?

백엔드에서 sender를 조작하는것은 risky한데, 프론트에서 본인이 보는 화면을 조작하는것은 큰 의미가 없지 않을까 싶어서요.

0

인프런 AI 인턴님의 프로필 이미지

안녕하세요, 인프런 AI 인턴입니다. hxcva1님.

질문 주신 내용에 대해 설명드리겠습니다. STOMP를 통한 웹소켓 연결에서 보안 인증 및 사용자 식별을 확실하게 유지하려면, 연결 과정에서의 인증 정보를 효율적으로 관리하는 것이 중요합니다.

현재 상황과 문제점

현재 설정에서는 웹소켓 연결 시 처음에만 JWT 토큰을 통해 인증을 하고, 이후의 메시지 처리에서는 이메일 정보에 의존하여 사용자를 식별하고 있다고 하셨습니다. 이는 중간에 사용자 정보가 일치하지 않거나 잘못된 사용자에게 메시지가 전송될 가능성을 열어둘 수 있습니다.

제안 솔루션

  1. 초기 인증 시 사용자 정보 저장:

    • 웹소켓 연결이 이루어질 때, 서버 측에서 JWT 토큰을 검증하여 해당 사용자의 정보를 식별합니다.
    • 이 정보를 세션 또는 컨텍스트 메모리에 저장하여 이후 메시지 저장 시 참조할 수 있도록 설정합니다.
  2. WebSocket Attribute 사용:

    • Spring에서 WebSocket 세션 객체에 속성을 넣고 가져오는 것이 가능합니다.
    • org.springframework.web.socket.WebSocketSession 클래스를 사용하여 사용자의 이메일과 같은 식별 정보를 초기 연결 시 속성에 저장해 두고, 이후 이 정보를 참조하여 메시지를 처리합니다.

    ”`java
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
    // JWT 토큰 인증 및 사용자 식별
    String userEmail = authenticateAndGetEmail(session);
    session.getAttributes().put(“userEmail”, userEmail);
    }

public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
String userEmail = (String) session.getAttributes().get(“userEmail”);
// userEmail을 이용하여 메세지 처리
}
“`

  1. 세션 기반 사용자 관리:
    • 메시지를 받을 때마다 세션에서 사용자 정보를 읽어 필요한 처리를 할 수 있도록 관리합니다.
    • 이렇게 함으로써, 항상 일관된 사용자 정보를 참조하여 메시지를 전송할 수 있습니다.

위 방법들은 기존의 이메일 기반 사용자 식별 방식에 비해 보안성과 정확성을 높이는 데 도움을 줄 수 있습니다.

아래의 질문과 답변을 통해 추가적인 정보를 얻으실 수 있습니다:
- WebSocket 인증 및 세션 관리에 대한 고찰

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

hxcva1님의 프로필 이미지

작성한 질문수

질문하기