1. 문제 상황 

  • 포스트맨으로 테스트를 했을 땐 잘 들어 가는데, 프론트에서 게시글 조회 하면 조회하는 이미지가 자꾸 엑박이 뜨고 아래와 같은 오류 메세지가 콘솔창에 떴다.  
  • Failed to load: resource: net::ERR_CERT_COMMON_NAME_INVALID
  • 확인해 보니 포스트맨에 나오는 이미지 url는 "https://namoldak.com.s3.ap-northeast-2.amazonaws.com/static/8c0ca99e-c76f-4ec5-90e1-8e6c4211" 라고 나오지만 AWS S3 버켓에서 해당 이미지 파일 주소를 확인했을 때는 "https://s3.ap-northeast-2.amazonaws.com/namoldak.com/static/8c0ca99e-c76f-4ec5-90e1-8e6c4211" 이렇게 다른 주소로 주소가 저장이 되어 있었다. 

2. 원인 

  • 버킷 이름에 .이 들어가면 Failed to load: resource: net::ERR_CERT_COMMON_NAME_INVALID 오류가 발생한다. 

 

3. 문제해결 

  • "namoldak.com" 인 버켓이름을 "namoldak"으로 바꿔 주었더니 바로 해결이 되었다 ! 

 


[ 참고 자료 ]

 

https://be-developer.tistory.com/85

 

[Spring Boot] aws s3 presignedUrl로 업로드 하는 법(One Time Token, OTT)

[Spring Boot] aws s3 presignedUrl로 업로드 하는 법 회사에서 이미지 업로드시 서버의 I/O 부하를 줄이기 위해 클라이언트에서 바로 aws의 S3에 업로드를 할 수 있도록 presignedUrl을 내리라는 미션을 받았다

be-developer.tistory.com

 

프로젝트를 진행하면서 에러가 발생할 경우 데이터가 잘 들어가는지 확인하기위해 로깅을 할 때가 자주 있다. 오늘은 스프링부트 lombok에서 제공하는 (@Slf4j)를 이용한 로깅법을 정리해보려 한다.

 

실제로 이번 프로젝트에 사용한 예제

 

Logging 이란? 

  • 로깅(logging)은 정보를 제공하는 일련의 기록인 로그(log)를 생성하도록 시스템을 작성하는 활동을 말한다.
  • 프린트 줄 넣기(printlning)는 간단한, 보통은 일시적인, 로그를 생성하기만 한다. 
  • 시스템 설계자들은 시스템의 복잡성 때문에 로그를 이해하고 사용해야 한다.
  • 로그가 제공하는 정보의 양은, 이상적으로는 프로그램이 실행되는 중에도, 설정 가능해야한다.

 

Logging 사용시 장점

  • 쓰레드 정보, 클래스 이름 같은 부가 정보를 함께 볼 수 있고, 출력 모양을 조정할 수 있다.
  • 로그 레벨에 따라 개발 서버에서는 모든 로그를 출력하고, 운영서버에서는 출력하지 않는 등 로그를 상황에 맞게 조절할 수 있다.
  • 시스템 아웃 콘솔에만 출력하는 것이 아니라, 파일이나 네트워크 등, 로그를 별도의 위치에 남길 수 있다. 특히 파일로 남길 때는 일별, 특정 용량에 따라 로그를 분할하는 것도 가능하다.
  • 성능도 일반 System.out보다 좋다. (내부 버퍼링, 멀티 쓰레드 등등) 그래서 실무에서는 꼭 로그를 사용해야 한다.

 

로그 선언 및 호출

 

//선언
private Logger log = LoggerFactory.getLogger(getClass());
private static final Logger log = LoggerFactory.getLogger(Xxx.class)

//lombok
@Slf4j

//호출
log.info("hello");

 

간단한 동작 예제

package hello.springmvc.basic;

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

//http body 에 string 을 넣어줌
// 기존 Controller 와 차이 있음
@RestController
@Slf4j //private... Logger 선언 귀찮을 때 대체할 수 있음
public class LogTestController {

//    private final Logger log = LoggerFactory.getLogger(getClass());

    @RequestMapping("/log-test")
    public String logTest(){
        String name = "Spring";

        //앞으로 이런방식 권장하지 않음
        System.out.println("name = " + name);

        log.trace(" trace my log="+ name);

        log.trace("trace log={}", name);

        log.debug("debug log={}", name);
        log.info(" info log={}", name);
        log.warn(" warn log={}", name);
        log.error("error log={}", name);
        return "ok";
    }
}
  • LEVEL : TRACE > DEBUG > INFO > WARN > ERROR
  • 개발 서버는 debug 출력
  • 운영 서버는 info 출력

올바른 사용법

  • log.debug("data="+data");
    • 로깅레벨이 debug 보다 높을 때에도 문자 더하기 연산이 수행됨(출력이 안되어도)
  • log.debug("data = {},data);
    • 의미없는 연산 발생하지 않음

 

 


[ 참고 자료 ]

 

문제 상황 

  • 프론트엔드와 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가 날라가진 않았는지 확인해보자 ! 

+ Recent posts