문제 상황 

  • 프론트엔드와 WebRTC를 테스트하는데 계속해서 위와 같은 에러가 떴다.
  • 백엔드 서버는 https:// 를 사용하고 있고, 프론트엔드는 http:// local 서버를 사용하는 상황
  • 채팅방에 클라이언트가 입장하면 해당 클라이언트 세션아이디를 Redis DB에 저장해주고 있다.
  • 처음 같은 채팅방에 다른 두 클라이언트가 들어가면 시그널링은 성공하는데, 둘 중 한명이 나가면 Redis DB에 그 방에 남아있는 사람들의 정보까지도 나랄가 버린다.... 와이 ... ? 
  • 근데 백엔드 서버와 프론트엔드서버 모두 로컬인 http://를 사용할때는 해당 에러가 없다 ! 

 

추측 원인

  • 테스트중인 소스의 signal 서버 프로토콜이 https인데 거기에 접속하는 페이지는 http 여서 발생하는 문제
  • 크롬37버전이상부터 http로는 미디어스트림을 얻을 수 없다.(getUsermedia 사용불가) 시그널 서버가 http건 https건 상관 없지만 getUsermedia를 사용하는 클라이언트가 https가아니면 사용 불가능 하다고 한다.

 

오늘은 시간이 늦어서 내일 프론트엔드 서버를 https://로 배포하면 다시 맞춰보는 걸로 ! 

 

추가

글 쓴 다음날 프론트엔드 서버를 https:// 로 바꿔 백엔드 서버와 똑같이 맞춰준 뒤 실험을 했지만 여전히 같은 에러가 발생한다.

왜일까 ...? ㅠ ㅠ WebRTC 정말 어렵다 ...!

해결하는대로 업데이트 하겠습니다 ㅠ ! 

 

--> 수정 ! 해결이 되었습니다 !! 원인과 해결방법은 아래 링크 참조해 주세요 : ) 

 

[13] 트러블 슈팅 : HTTPS 배포 유의사항

 

[13] 트러블 슈팅 : HTTPS 배포 유의사항

문제 상황 생각보다 WebRTC 시그널링 연결이 오래 걸렸는데, http인 로컬 서버로만 했을 때는 문제없던 기능들이 https 서버로 환경을 바꿔주었더니 틈만나면 아래와 같은 에러 혹은 403, 404, 405에러,

leejincha.tistory.com


[ 참고 자료 ]

문제 상황

Front와 협업중에 구매한 도메인을 적용했고 서버에서 데이터를 문제없이 내려주기 위해서 CORS에 해당 도메인을 등록했다. 해당 도메인을 등록하고 나니까 localhost:3000 [즉, 프론트쪽 리액트 local] 에서 spring 서버로 접근이 안되는 현상이 발생했다.

 

  • 문제 발생했을 때 코드

  • 수정된 코드

  • allowedOrigins 대신 allowOriginPatterns를 사용

일단 이렇게 해서 해결이 되긴 했는데, 이 글을 쓰면서 관련 에러를 더 찾아보니 새로운 사실을 알게 되었다.

 

원인 / 해결 방법  (추측임 , 확실하지 x)

 (어느블로그에서 본 글이기 때문에 정확한 정보라고 볼 순 없을 것 같다.)

  • AllowedOrigins()은 중복해서 사용할 수 없다. 중복할 경우 값이 계속해서 덮어씌여지면서 앞에 Setting 값들이 다 날아간다.

즉, 올바른 사용은 다음과 같다.

  • .setAllowedOrigins("http://localhost:3000", "http://--------.cloudfront.net") 으로 사용하거나
  • .setAllowedOrigins("*")를 사용해준다.

-----> 수정 !! 

  • .setAllowedOrigins("http://localhost:3000", "http://--------.cloudfront.net") 으로 사용해도 에러가 난다.
  • 결론은 setAllowedOriginPatterns 를 사용해야만 해결이 되었다 ! 

 

추가

setAllowedOriginPatterns vs setAllowedOrigins ? 

( 자료출처 스프링 공식 문서 : https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/cors/CorsConfiguration.html )

public void setAllowedOrigins(@Nullable List<String> origins)
A list of origins for which cross-origin requests are allowed where each value may be one of the following:
  • a specific domain, e.g. "https://domain1.com"
  • comma-delimited list of specific domains, e.g. "https://a1.com,https://a2.com"; this is convenient when a value is resolved through a property placeholder, e.g. "${origin}"; note that such placeholders must be resolved externally.
  • the CORS defined special value "*" for all origins

For matched pre-flight and actual requests the Access-Control-Allow-Origin response header is set either to the matched domain value or to "*". Keep in mind however that the CORS spec does not allow "*" when allowCredentials is set to true and as of 5.3 that combination is rejected in favor of using allowedOriginPatterns instead.

By default this is not set which means that no origins are allowed. However, an instance of this class is often initialized further, e.g. for @CrossOrigin, via applyPermitDefaultValues().

 

 

 

public CorsConfiguration setAllowedOriginPatterns(@Nullable List<String> allowedOriginPatterns)

 

Alternative to setAllowedOrigins(java.util.List<java.lang.String>) that supports more flexible origins patterns with "*" anywhere in the host name in addition to port lists. Examples:
  • https://*.domain1.com -- domains ending with domain1.com
  • https://*.domain1.com:[8080,8081] -- domains ending with domain1.com on port 8080 or port 8081
  • https://*.domain1.com:[*] -- domains ending with domain1.com on any port, including the default port
  • comma-delimited list of patters, e.g. "https://*.a1.com,https://*.a2.com"; this is convenient when a value is resolved through a property placeholder, e.g. "${origin}"; note that such placeholders must be resolved externally.

In contrast to allowedOrigins which only supports "*" and cannot be used with allowCredentials, when an allowedOriginPattern is matched, the Access-Control-Allow-Origin response header is set to the matched origin and not to "*" nor to the pattern. Therefore, allowedOriginPatterns can be used in combination with setAllowCredentials(java.lang.Boolean) set to true.

By default this is not set.

Since:5.3

 

정리

스프링부트 5.3부터 allowCredentials가 true일 때 allowedOrigins에 특수 값인 "*" 추가할 수 없게 되었다. 대신 allowOriginPatterns를 사용해야 한다. 

근데 이 이유때문에 발생한 오류는 아니었을 것 같다는 느낌 ... 아시는분 댓글 부탁드립니다 ! 


[ 참고 자료 ]

 

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/cors/CorsConfiguration.html 

 

CorsConfiguration (Spring Framework 6.0.4 API)

Alternative to setAllowedOrigins(java.util.List ) that supports more flexible origins patterns with "*" anywhere in the host name in addition to port lists. Examples: https://*.domain1.com -- domains ending with domain1.com https://*.domain1.com:[8080,8081

docs.spring.io

 

https://evan-moon.github.io/2020/05/21/about-cors/

 

CORS는 왜 이렇게 우리를 힘들게 하는걸까?

이번 포스팅에서는 웹 개발자라면 한번쯤은 얻어맞아 봤을 법한 정책에 대한 이야기를 해보려고 한다. 사실 웹 개발을 하다보면 CORS 정책 위반으로 인해 에러가 발생하는 상황은 굉장히 흔해서

evan-moon.github.io

 

https://cotak.tistory.com/248

 

[트러블슈팅] CORS 설정 시 allowedOrigins 에러

개요 CORS 필터를 분명 적용했는데, CORS에러가 발생해서 디버깅을 해봤더니 다음과 같은 에러가 발생했다. When allowCredentials is true, allowedOrigins cannot contain the special value "*" since that cannot be set on the "

cotak.tistory.com

 

 

JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted 에러가 발생되는 경우

 

→ 해당 에러는 토큰 검증시 시간이 만료되거나 key가 변경되어 맞지 않을때 발생되는 문제이다.

토큰값이 일치하는지, 토큰이 유효한지, 혹은 서버가 내려간건 아닌지, DB가 날라가진 않았는지 확인해보자 ! 

문제상황

  • WebRTC를 이용해 프론트엔드와 화상채팅을 구현하는 코드를 작성 중이다.
  • 채팅방에 들어오는 사람마다 session ID를 갖고있는데, 이 세션 아이디를 Redis DB에 저장하는 과정에서 아래와 같은 두 가지 에러가 발생했다.
  • Jackson ObjectMapper를 사용해서 객체타입인 세션을 스트링타입으로 변환해주고 다시 객체타입으로 변환하는 그런 로직에 사용했는데, 이 부분에서 에러가 터진 것 같다. (추측)

1. No serializer found for class org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)

 

2. Null key for a Map not allowed in JSON (use a converting NullKeySerializer?)

 

원인 : 모름

해결 : 못함

 

 

[ 참고자료 ]

https://interconnection.tistory.com/137

 

Jackson ObjectMapper 정리

개요 Java 개발자라면 Jackson에서 제공하는 ObjectMapper와 자주 마주치게 됩니다. Java 클래스 내용을 확인하거나 내용물의 Parsing 과정에 필요한 커스터마이징이 존재하기 때문입니다. 물론 중요한 기

interconnection.tistory.com

https://jinseongsoft.tistory.com/248

 

[SpringBoot] Jackson 사용시 Could not write JSON: No serializer found for class.. 오류 발생 해결법

들어가며 Class를 Serialize 하는 과정에서 아래와 같은 에러가 발생하였다. Exception in thread "Thread-5" org.springframework.messaging.converter.MessageConversionException: Could not write JSON: No serializer found for class com.tact.

jinseongsoft.tistory.com

 

 

이번 프로젝트에 WebSocket/Stomp 를 이용해 채팅기능을 구현하면서 프론트에 전달하는 messageType에 Enum을 사용하게 되었다. 내가 구현한 코드부분이 아니기도하고 Enum에 대한 개념이해가 부족해서 정리해보려 한다.


Enum 이란?

  • Enum이란 enumerated type의 줄임말로 열거형이라고 불리며 서로 연관된 상수들의 집합을 의미한다.
  • 흔히 상수를 정의할 때 final static string 과 같은 방식으로 상수를 정의한다. 하지만 이렇게 상수를 정의해서 코딩하는 경우 다양한 문제가 발생하는데, 이러한 문제점들을 보완하기 위해 자바 1.5버전부터 새롭게 추가된 것이 바로 "Enum" 이다.
  • 기존에 상수를 정의하는 방법이였던 final static string 과 같이 문자열이나 숫자들을 나타내는 기본자료형의 값을 Enum을 이용해서 같은 효과를 낼 수 있다.

 

Enum의 장점

  • IDE의 지원을 받을 수 있다. 자동완성, 오타검증, 텍스트 리팩토리 등
  • 허용 가능한 값들을 제한할 수 있다.
  • 리팩토링 시 변경 범위가 최소화 된다. 내용을 추가해도 Enum 코드만 수정하면 된다.
  • 확실한 부분과 불확실한 부분을 분리할 수 있다.
  • 문맥(Context)을 담을 수 있다.
  • 코드가 단순해지며, 가독성이 좋다.
  • 인스턴스 생성과 상속을 방지하여 상수값의 타입안정성이 보장된다.
  • enum class를 사용해 새로운 상수들의 타입을 정의함으로 정의한 타입이외의 타입을 가진 데이터값을 컴파일시 체크한다.
  • 키워드 enum을 사용하기 때문에 구현의 의도가 열거임을 분명하게 알 수 있다.

 

Enum 사용시 주의점

  • Enum을 사용하는데 있어 가장 큰 허들은 "변경이 어렵다"란 점
  • 코드를 추가하거나 변경해야 하는 일이 빈번하다면, 매번 Enum 코드를 변경하고 배포하는것보다 관리자 페이지에서 관리자가 직접 변경하는 것이 훨씬 편리할 수 있다.
  • 위와 같은 경우 테이블로 관리함으로써 얻는 장점이 정적언어를 활용함으로써 얻는 장점을 버릴정도로 더 큰지 고민해봐야 한다.

[ 참고자료 ]

 

https://eatnows.tistory.com/91

 

Enum이란?

Enum이란? enum이란 enumerated type의 줄임말로 열거형이라고 부르기도 하는데 컴퓨터 프로그래밍에서 열거형(enumerated type, enumeration)은 요소, 멤버라 불리는 명명된 값의 집합을 이루는 자료형이다.

eatnows.tistory.com

https://limkydev.tistory.com/50

 

[Java] enum 이란?

Enum class란? 우리가 흔히 상수를 정의할 때 final static string 과 같은 방식으로 상수를 정의를합니다. 하지만 이렇게 상수를 정의해서 코딩하는 경우 다양한 문제가 발생됩니다. 따라서 이러한 문제

limkydev.tistory.com

https://techblog.woowahan.com/2527/

 

Java Enum 활용기 | 우아한형제들 기술블로그

{{item.name}} 안녕하세요? 우아한 형제들에서 결제/정산 시스템을 개발하고 있는 이동욱입니다. 이번 사내 블로그 포스팅 주제로 저는 Java Enum 활용 경험을 선택하였습니다. 이전에 개인 블로그에 E

techblog.woowahan.com

 

+ Recent posts