본문 바로가기

node.js - axios / CORS / apollo-server / graphQL-API(&docs) 생성 본문

개발/node.js

node.js - axios / CORS / apollo-server / graphQL-API(&docs) 생성

자전하는명왕성 2023. 1. 14. 02:44

axios

 

axios는 node.js를 위한 Promise API를 활용하는 HTTP 비동기 통신 라이브러리다.

쉽게 말해, 백엔드와 프론트엔드 간 통신을 쉽게하기 위해 사용한다. (백엔드, 프론트엔드 둘다 가능)

이번 포스팅에서는 HTML내에 axios를 설치하고 적용하는 방식에 대해 설명한다.

 

해당 코딩은 이전에 만든 휴대폰 번호 토큰 전송 기능을 활용한다.

axios 설치는 npmjs에 제시된 cdn을 통해 완료했다.

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

먼저 프론트엔드(가상) 내에 axios 통신이 구현됨을 확인하기 위해 HTML을 만들었다.

이때, '인증하기' 버튼을 누르면, zzz() 라 이름지은 함수가 실행되게 되는데 그 함수의 모습은 이렇다.

function zzz(){
                // 1. 입력한 휴대폰 번호 가져오기
                const myPhone = document.getElementById('myPhone').value
                console.log("나의 핸드폰 번호", myPhone)

                // 2. 해당 핸드폰번호로 API 요청하기 (fetch, axios 등 사용)
                axios.post("http://localhost:3000/tokens/phone", {
                    qqq : myPhone
                }).then((res) => {
                    console.log(res.data)
                    document.getElementById('result').innerText = res.data
                })
            }

 

로직은 어렵지 않다. Input 창에 입력된 번호를 변수 myPhone 에 담은 뒤, 

axios.post 로 qqq를 'key'로 갖는 변수 myPhone이 생성된다.

 

다음은 post 된 qqq가 갖는 값을 가져오기 위해 백엔드에도 요청 & 응답을 할 수 있는 함수를 작성해준다.

// 백엔드 index.js

app.post("/tokens/phone", function (req, res) {
    console.log(req);
    
    let myPhone = req.body.qqq;		  // 키 qqq에 담긴 데이터 요청

    const isValid = checkPhone(myPhone);  // 정상적인 휴대폰 번호인지 검증
    if (isValid == false) return;

    const myToken = getToken();		  // 랜덤한 번호 ######를 생성하는 토큰

    sendTokenToSMS(myPhone, myToken); // 위 모든 함수를 정상적으로 거칠 시
				      // qqq가 갖는 번호로 인증번호 ######을 전송한다.

    res.send("인증 완료!");
});

 

이후 번호를 입력하고 인증버튼을 누를 시 아래와 같이 '인증상태'가 '인증완료'로 대체되며

터미널에는 아래와 같이 정상적으로 번호와 토큰 전송이 되었음을 확인할 수 있다.

 

CORS

사실 위 과정을 진행하면서 CORS Policy 오류를 받게 되었다.

이는 localhost:3000(프론트엔드) 와, localhost:4000(백엔드)가

각기 다른 포트 번호로 통신하면서 생기는 오류였다. 이제 CORS에 대해 알아보자.

 

기존 SOP(same origin policy) 의 데이터통신 불편을 대체하기 위해 나온 것이 

CORS(cross origin resourse sharing) 라고 한다.

단, CORS 허용이 되었다고 해도 바로 통신이 되는 것이 아니라,

먼저 preflight 를 통해서 CORS 가 허용되어 있는지, 어떤 CRUD가 가능한지 확인한 뒤 API 통신 진행하고,

만약, 요청하는 백엔드에서 CORS가 거절되어 있다면 '브라우저'에서 API 요청을 차단한다.

(위에서 내가 겪은 상황이 그랬다.)

요령으로는 본 브라우저에서 본 백엔드에 API 요청 후, 본 백엔드에서 타 백엔드로 데이터 통신이 가능한데, 이를 proxy 서버라고 한다. (차단은 브라우저가 하기 때문에, 이를 우회한 방식이라고 볼 수 있다.)

** 모바일도 proxy 서버를 활용하는 것이 가능하다.

 

**추가로 CORS 는 백엔드를 보호하려고 존재하는 것이 아니라, 브라우저를 보호하기 위해 존재한다고 한다. (CSRF 공격에 대한 방어)

 

어쨌든 이를 해결하기 위해서는 CORS 를 허용해주는 과정이 필요했다.

사실 이는 어렵지 않다. 

npmjs 사이트에서 CORS를 다운 받은 뒤,  https://www.npmjs.com/package/cors 

사이트에 제시된 다음과 같은 기본 코딩을 해주면 CORS 오류는 나타나지 않게 된다.

// CORS 설정 코딩
// 백엔드 index.js

import cors from 'cors'
app.use(cors())

// package.json

"cors": "^2.8.5", // yarn add cors 시 자동 생성

 

apollo-server

아폴로 서버는 GraphQL-API를 제공하는 서버를 개발할 수 있게 도와주는 패키지로, 

기존 node.js 에서 사용하는 express와 역할이 비슷하다. (다만,  작동 코딩과 작동 코딩 docs를 함께 만들어줘야 한다.)

apollo-server 역시 다운로드가 필요하다.https://www.npmjs.com/package/@apollo/server

이후 사이트에 제시된 초안을 붙여준다.

이때, resolvers는 API

이때, typeDefs는 API docs를 의미한다.

 

GRAPHQL API & GRAPHQL API docs 생성

이후 생성하기 위한 코딩은 아래와 같다.

// docs 부분
const typeDef = `#graphql		//typeDef 는 백틱으로 감싸야 함
	type BoardReturn {
        number: Int
        writer: String
        title: String
        contents: String
    }
    // 중략 //
}`

// API 실행 부분
const resolvers = {
    Query: {
        fetchBoards: (_, args) => {
            return [
                {
                    number: 1,
                    writer: "철수",
                    title: "제목입니다",
                    contents: "내용입니다",
                },
                {
                    number: 2,
                    writer: "영희",
                    title: "좋은 날씨입니다",
                    contents: "내용입니다",
                },
            ];
        },
    },

이후 적용된 페이지

 

API를 가져와 프론트엔드에 응답하는 과정을 연습하는 과제 완성샷

axios.get을 통해 API 데이터를 동기적으로 바꿔 호출하는 것이 키워드였다.

 

Comments