ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [SW 정글 105일차] 나만의 무기 13일차 (오늘 새로 배운 것)
    기타/SW 사관학교 정글 2021. 11. 15. 23:37

    오늘은 로그인, 로그아웃 api를 프론트와 연동하는 것을 완성했다.

    내가 맡은 부분은 아니고 로그인 api를 맡은 조원이 많은 고민을 하는 것을 옆에서 문제 공유를 하고 내 할 일을 끝나면 잠깐잠깐 도와주면서 해결과정 중에 배운 점들을 정리하려고 한다.

     

     

     

     

    1. client에서 보낸 form data를 json으로 바꿔서 보냈는데 서버에서 못 받는다..

    로그인은 client에서 form페이지에서 유저에게 데이터를 받아서 POST로 보내는 형식이다.

    form data를 json으로 보내기 위해 request header를 "Content-Type": "application/json; charset=utf-8"로 설정해줬다.

    그리고 JSON.jsonify(data)를 해서 json형태로 바꿔주기도 했다.

    client에서는 보낼 준비를 완벽히 했는데 서버에서 로그를 찍어보니까 처음에는 undefined라고 찍혔다.

    그래서 구글링을 해서 알아낸 결과는 아래와 같다.

    app.js (서버코드)에 아래 2lines를 추가해주면 된다.

    app.use(express.json()); // json을 받아들이게 해줌.
    app.use(express.urlencoded({extended : false})); // {} 빈 object로 받아지는 것을 해결해줌.
    
    // body-parser라는 node.js모듈을 추가하면 되지만
    // Express v4.16.0 기준으로 express.js에서 자체 제공하기 때문에 따로 import 할 필요가 없다.

    하지만, 이렇게 해도 해결이 되지 않았다...

    POSTMAN을 사용하여 요청을 보낼 때에도 json으로 보내면 api가 동작을 하지 않았고 x-www-form-urlencoded 형태로 보내지면 동작을 했다.

    그래서 client에서 application/x-www-form-urlencoded 형식으로 보내도록 data를 reform하고 보내도록 했다.

    일단 동작은 했지만 계속해서 이 방법을 사용할 수 없고 그렇다고 계속 이거를 잡기에는 시간이 부족했다.

    그리고 json을 못받는 문제 이외에도 로그인 API 동작에 다른 문제가 존재했다.

    일단은 넘기고 다른 문제를 해결하려고 한 도중에 조장님이 문제를 해결해줬다.

    (나도 어제 새벽에 몇 시간 동안 건들건들했는데 해결하지 못한 문제를... 역시 조장님이다!)

     

    문제를 일으킨 원인은 엄청 간단하지만 반드시 알고 넘어가야 한 것이였다.

    원인은 middleware 선언 순서가 잘못됐기 때문이다.

    알고나서 '이런 사소한 것때문에 동작을 안했다니..'라는 생각도 들었지만 이것도 nodejs express를 다루면서 이것도 신경안썼다니..'라는 생각도 들었다.

    express를 하나의 application으로 사용하면서 다양한 기능을 하는 middleware를 붙여주는 형태인데 붙여주는 것에 순서가 중요하다.

    기존에는 선언 순서가 router를 use하는 코드 아래에 body-parser를 해주어 json으로 변경해주는 middleware를 use하게 해주었다.

    순서 상 맞지 않았고 body-parser를 해주어 json으로 변경해주는 middleware를 앞에 선언해주었더니 정상적으로 json타입 데이터를 받을 수 있었다.

    기본에 충실하자...

     

     

     

     

    2. 브라우저에 세션ID를 가지는 쿠키가 저장이 안된다...

    유저가 브라우저에서 url을 입력하여 서버에 접속하면 세션이 만들어진다.

    그리고 우리는 로그인 방식으로 세션을 사용하기 때문에 로그인 성공 시에 세션ID를 쿠키로 클라이언트에게 넘겨준다.

    하지만, 브라우저가 세션ID가 담긴 쿠기를 받지 못한다.

    그리고 계속해서 새로운 세션이 서버에서 생성된다.

    새로운 세션이 서버에서 생성된다는 것은 브라우저가 요청을 보낼 때 새로운 클라이언트로 인식한다는 것인데 문제가 무엇일까 고민을 했다.

    문제의 원인은 cors였다.

    cors라는 말은 프로젝트를 시작하기 전에 종종 들었지만 실제로 접해본 것은 처음이다.

    지금 쿠키를 받지 못하는 것 전에도 로그인 api와의 연동이 안되는 것도 cors문제였었다.

    CORSCross-Origin Resouces Sharing으로 Cross-Site Http Request를 가능하게하는 표준 규약이다.

    웹브라우저가 XMLHttpRequest나 Fetch API로 외부서버의 데이터에 접근하려는 경우 SOP에 의하여 cross-origin문제가 발생하지만 CORS를 사용하여 해결할 수 있다.

    SOPSame Origin Policy으로  하나의 origin으로부터 로드된 문서나 스크립트가 다른 origin의 자원과 상호작용 하지 못하도록 제한하는 것이다.

     

    우리는 프론트 서버가 3000포트로 열려있고 api는 5000포트로 열여있다.

    즉, 화면을 구성해주는 JS, CSS는 3000포트에서 받아오면서 api요청을 통해 데이터를 받아오려면 5000포트에 요청을 보내야한다는 것이다.

    http://localhost:3000과 http://localhost:5000은 뒤에 포트번호만 다를 뿐이지만 이것은 SOP를 위반하는 행위이다.

    그래서 CORS를 사용하여 문제를 해결하도록 해줄 수 있다.

    혹은 3000 포트번호를 가진 proxy를 두어서 proxy가 대신해서 5000포트와 연결하여 데이터를 받아오고 다시 클라이언트에게 보내주도록 할 수 있다고한다.

    일단은 CORS를 사용하여 api가 연동되도록 하는 것은 해결했다.

    하지만, 아직도 쿠키가 들어오지를 않는다...

     

    쿠키 문제는 아래의 블로그를 참고해서 해결했다.

    https://kosaf04pyh.tistory.com/152

    // 서버 코드
    app.use(
      cors({
        origin: "http://localhost:3000", // <-- location of the react app were connecting to
        credentials: true,
      })
    
    // 클라이언트 코드
    export default axios.create({
      baseURL,
      headers: {
        "Content-Type": "application/json; charset=utf-8",
      },
      // `withCredentials` indicates whether or not cross-site Access-Control requests
      // should be made using credentials
      withCredentials: true,
    });

     

    CORS에 대해 조금 더 공부해도고 세션도 지금 의문을 가진 점이 해결되지 않아서 더 찾아봐야겠다.

     

     

     

    <해야 할 일>

    DB 다시 모델링하기, db naming rule 정하기

    -> 이유는?

    일단은 api를 짜기 시작하면서 기존에 작성한 초안 model이 많이 수정되고 오늘 멘토링을 받으면서 foreign key constaint가 이루어져 잘못된 데이터를 삽입하는 것을 막을 수는 있지만 현업에서는 foreign key를 설정하는 것을 지향하지는 않는다고 했다.

    그래서 foregin key 설정도 바꿔야하고 수정할 부분을 수정할 계획이다.

    또한, 처음에 테이블을 생성하고 column을 생성할 때 naming을 불규칙하게 정해서 sql문을 작성할 때 불편함을 느끼고 있다.

    이 부분을 naming rule을 정하여 규칙성있게 바꿀 계획이다.

     

    댓글

Designed by Tistory.