눈치, 코치, 캐치! (try’S ketch)

FE.

- Client 와 Server 의 차이점? Git Repo를 보니 React 를 Client 라고 명명하여서 질문

서버는 클라이언트에게 서비스를 제공하는 제공자이고, 클라이언트는 사용자로부터 입력을 받아 서버와 통신하고 사용자에게 결과를 제공하는 소프트웨어입니다.

해당 프로젝트에서는 EC2에 업로드 된 간단한 node.js 서버로 서버사이드 렌더링을 진행시키고 있지만, git repo에 업로드 된 코드들은 사용자에게 입력을 받고 Spring으로 작성된 메인 서버에 전달하며, 서버로부터 온 response들을 알맞게 처리하여 사용자에게 보여주는 역할을 하고 있습니다.

따라서 client의 정의에 따라 해당 프로젝트의 react는 사용자에게 입력을 받고, 서버와 통신하며, 결과를 제공하는 소프트웨어이기 때문에 client로 명명하였습니다.

⇒ 서비스 전체적인 측면에서 frontend는 backend-server 측에 데이터를 요청하고 수신한 정보로 화면에 출력합니다. 사용자 측면에서 동작하는 부분이라는 점에서 client라고 명명하여도 문제없다고 판단하였습니다.

- API 호출에 있어서 공통된 에러 처리를 하지 않은 이유? 앞으로의 전략?

최초에 공통적인 에러 상황을 처리하려고 하였으나, 각각의 요청에 대한 명세와 그에 대한 공통된 에러 상황이 불분명하였기 때문에 작업 우선순위에서 후순위에 위치하였습니다.

axios의 *interceptors*를 이용해서 각각의 에러 상황과 에러 코드에 대한 명세를 맞춰서 상황에 맞게 공통적으로 처리하려고 합니다.

예를 들어서, 서버에서 다양한 에러로 발생하는 500, unauthorized 401 과 같은 공통적인 에러에 대해서 각각의 요청에서 중복된 처리를 하지 않도록 할 예정입니다.

- withCredentials 는 왜 붙이는지에 대한 이해가 있다면 설명

withCredentials는 서로 다른 도메인(크로스 도메인)에 요청을 보낼 때 요청에 credential 정보를 담아서 보낼 지를 결정하는 항목입니다.

여기서, credential 정보가 포함되어 있는 요청은 아래 두 가지 경우를 의미합니다.

  1. 쿠키를 첨부해서 보내는 요청
  2. 헤더에 Authorization 항목이 있는 요청

따라서, 보내고자 하는 요청이 위 두 가지 항목 중 한 가지라도 포함하고 있다면 withCredentials 옵션을 **true**로 설정해야만 합니다.

⇒ frontend에서 credential 정보가 담겨있는 요청을 하기 때문에 WithCredentials를 명시해주었습니다.

- CORS 란 무엇이고 어떻게 해결해야하는가

브라우저에서는 보안적인 이유로 cross-origin HTTP 요청들을 제한합니다. 그래서 cross-origin 요청을 하려면 서버의 동의가 필요합니다. 만약 서버가 동의한다면 브라우저에서는 요청을 허락하고, 동의하지 않는다면 브라우저에서 요청을 거절하게 됩니다.

이러한 메커니즘은 HTTP-header를 이용해서 허락되거나, 또는 거절되는데 이를 CORS(Cross-Origin Resource Sharing)라고 부릅니다.

cross-origin

cross-origin이란 다음 중 한 가지라도 다른 경우를 말합니다.

  1. 프로토콜
  2. 도메인
  3. 포트 번호

즉, 프로토콜 + 도메인 + 포트 번호가 같으면 동일 출처입니다.

Why CORS??

만약 CORS가 없이 모든 곳에서 데이터를 요청할 수 있게 되면, 다른 사이트에서 원래 사이트를 모방할 수 있게 됩니다. 개발자 도구만 열더라도 각종 코드를 쉽게 열람할 수 있는데 이를 이용해 사용자가 악의를 가지고 원래 사이트를 모방하여 사용자가 로그인을 하도록 유도하고 로그인했던 세션을 탈취하여 악의적으로 정보를 추출하는 등 보안적인 문제가 발생할 수 있습니다.

CORS 해결법

  1. 브라우저 설정에서 SOP정책을 비활성화한다

  2. 프록시 서버를 이용한다.

    CORS 에러는 클라이언트와 서버 사이에서 발생하기 때문에 모든 출처를 허용한 프록시 서버를 통해 요청을 하는 방식이다. 다만 현재 무료 프록시 서버 대여 서비스들은 악용 사례 때문에 모두 api 요청 횟수 제한을 두어 실전에서 사용하기에는 무리가 있다. 따라서 실전에서는 직접 프록시 서버를 구축해야한다.

  3. 서버에서 Access-Control-Allow-Origin 헤더 세팅하기

    브라우저에서 서버에 요청을 보낼 때 요청 헤더에 Origin이라는 필드에 출처를 함께 담아 보내게 됩니다. 그리고 서버는 응답헤더에 Access-Control-Allow-Origin을 담아 클라이언트로 전달합니다. 브라우저에서는 자신이 보냈던 요청의 Origin과 서버가 보내준 Access-Control-Allow-Origin을 비교하여 유효하지 않다면 그 응답을 사용하지 않고 버립니다.(CORS 에러)

    따라서, 서버에서 Access-Control-Allow-Origin헤더에 클라이언트의 출처를 허용해주면 브라우저에서 CORS 에러를 발생시키지 않습니다. (가장 보편적인 해결 방법입니다.)

- Frontend에 CORS 헤더들을 세팅한 것이 보이는데 의도가 무엇인지? CORS 에 대해 설명할것

const instance = axios.create({
  baseURL: process.env.REACT_APP_API_URL,
  headers: {
    'Access-Control-Allow-Origin': '*',
  },
});

response 헤더

response 헤더

Access-Control-Allow-Origin헤더는 서버에서 보내주는 응답에 명시하는 부분이기 때문에 request 헤더에 있던 Access-Control-Allow-Origin은 삭제하였습니다.

- source map 숨기기

  1. .env 파일에 명시하기

    GENERATE_SOURCEMAP=false
    

    .env 파일에 추가하면 빌드시 .map 파일을 생성하지 않음

  2. package.json의 build 명령어

    "build": "GENERATE_SOURCEMAP=false react-scripts build",
    "winBuild": "set \\"GENERATE_SOURCEMAP=false\\" && react-scripts build",
    

    (build ⇒ linux 환경에서의 빌드 명령어, winBuild ⇒ window 환경에서의 빌드 명령어)

BE.

- 여러 기수의 프로젝트에 의아한 부분이었는데, Redis 는 메모리 기반의 DB 이지만 휘발성을 가진 것은 아니다. 그러면 DB 가 아니라 Cache 정도로 명명하지 않았을지