Week5 회고

이태성·2022년 4월 13일
0

항해99

목록 보기
5/9

서론

이번주에는 간단하게 CORS란 무엇인지, formData라는건 언제 사용하는지 알아보도록하자.
진행 순서는 다음과 같다.

  • CORS
  • formData의 활용

본론

A. CORS(교차 출처 자원 공유, Cross-Origin Resource Sharing)

  • 브라우저에서 다른 출처의 리소스를 공유하는 방법 또는 정책

    CORS 에러의 예시
    보통은 서버측에서 CORS문제를 해결해줘야 함.
    오늘은 어떤 이유로 발생하는지, 해결법은 무엇인지 알아보자.

  • URL 구조 이해하기

    • 출처라는게 무엇인지 이해가 안될텐데, 출처를 이해하기 위해서는 URL구조를 이해해야한다.
      HTTP 프로토콜의 포트번호는 80번, HTTPS 프로토콜의 포트번호는 443번으로 지정되므로 해당 프로토콜을 쓸때는 따로 포트번호를 기입할 필요가 없다.
  • 출처(Origin)란?
    URL 구조에서 살펴본 Protocal, Host, Port를 합친 것을 말한다.
    브라우저 개발자 도구의 콘솔 창에 location.origin를 실행하면 출처를 확인할 수 있다.

  • 같은 출처 VS 다른 출처
    그러면 이때, 같은 출처와 다른 출처 기준의 이해를 돕고자 아래의 표를 살펴보겠다.

  • CORS 동작 시나리오

    1. POSTman이나 Thunder Client 등으로 API를 테스트 할때는 무사히 응답이 온다.
    2. 브라우저에서 API를 호출할때만 CORS policy 에러가 발생한다.
    3. 브라우저가 동일 출처 정책(Same-Origin Policy, SOP)를 지켜서 다른 출처의 리소스 접근을 금지 하기 때문이다.
    4. SOP를 지키면 외부 리소스를 가져오지 못해 불편하지만 XSS, XSRF 등의 보안 취약점을 노린 공격을 방어 할 수 있다.
    5. 하지만 현실적으로 외부 리소스를 참고하는 것은 필요하므로 SOP의 예외 조항이 필요하다.
    6. SOP의 예외 조항이 바로 CORS다.
  • CORS 해결방법

    • 원래는 Simple request조건을 만족하여 통신하는 방법, Preflight request요청방식을 이용하는 방법이 있지만, 대체로 간편한 방법이라고는 말하기 힘들다.
    • node.js Express에는 cors라는 서드 파티 미들웨어를 지원하므로 라이브러리 설치 후 cors()라는 미들웨어 사용으로 간단히 해결 가능하다.

B. formData의 활용

종종 클라이언트가 업로드한 사진파일을 서버가 받아야하는 상황이 온다. 처음엔 단순히 req.body에 담겨서 오나? 했지만 어림도 없었다. 해결법은 아래와 같다.

  • formData 활용하기 (Front-end측 조치사항)

     const formData = new FormData();
            if(fileInput.current){
                formData.append('articleThumb', imgFile) // imgFile: ##.jpg, ##.png 등등
                formData.append('articleDesc', descripction) // descripction: string (bodyData)
                formData.append('articleKind', kind) // kind: string (bodyData)
            } 
    const addPostDB = (formData, token) => {
      return function(dispatch, getState){
        axios({
          method : 'post',
          url : 'http://hostname/api/articlePost',
          data : formData, // 위에서 append한 data들이 들어있음(사진, bodyData)
          headers : {
            Authorization : `${token}`, // 로그인 토큰인데 상황따라 필요 없을 수 있음
            'Content-Type': 'multipart/form-data', // 사진이랑 body데이터 같이 넘길때 필요(여러가지 타입 보낼때 유용)
          },
        })
        .then(response=>{
          console.log(response)
        })
        .catch(error =>{
          console.log(error)
        })
      }
    }
  • formData를 받기위한 라이브러리 사용 (Back-end측 조치사항)

    const multipart = require("connect-multiparty"); // 라이브러리 불러오기
     const multipartMiddleware = multipart({ uploadDir: "uploads" }); // 사진파일 담을 폴더생성
     router.post("/articlePost", multipartMiddleware,
      async (req, res) => {
        try {
          // body로 데이터 받기
          const { articleDesc, articleKind } = req.body;
    	  // 이미지 파일받기(updoads폴더에 임의의 파일명으로 저장됨)
          // req.files.articleThumb.path --> 저장된 이미지 파일의 경로
          let articleThumb = req.files.articleThumb.path; // 해당경로 자체를 string으로 DB에 저장한다.
          // 정상응답
    	  res.status(200).json({ result: true });
        } 
        catch (error) {
          console.log(error);
          console.log("articles.js -> 게시글 등록에서 에러남");
          res.status(400).json({ result: false });
        }});

    대강 이런 느낌으로 Front-end와 Back-end가 합을 맞추면 무사히 사진파일을 넘겨 받을 수 있다! formData를 활용안하고 그냥 넘기려고 하면 payload too large와 같은 용량 문제로 못보낸다는 에러를 만나게 될 것이다~~

결론

이번주 부터는 팀플을 시작하게 되었는데 드디어 BE, FE가 만나서 협업하는 첫 과정이라고 할 수 있다. 서로 이해도 많이해주고 배려도 해주면서 무사히 프로젝트를 끝마치는게 목표다!

profile
재밌게 뚫고 나가자

0개의 댓글