API와 통신1(API, CORS, 간단한 경험)

codeFug·2024년 1월 4일

JS

목록 보기
6/8
post-thumbnail

API

Application Programming Interfaces

서버는 외부에서 쓰기 위한 데이터를 전달하기 위해 만들어졌고 흔히 APIs라고 불린다.

API는 url을 통해 접근되고 이 url을 쿼리하는 세부적인 것은 우리가 사용하는 서비스에 따라 다르다.

보통 api를 사용하는 세부사항은 service의 website에 문서화 되어 있다.

물론 보통 계정을 만들어서 API key를 발급받은 후에 endpoint에서 data를 fetch해야 한다.
(endpoint : API에 있는 함수나 데이터에 접근하는 특정 URL)

API가 존재하면 다른 시스템이나 데이터에 대한 남용을 추적할 수 있다

그렇다면 어떤 식으로 API를 연결하여 data를 외부 서버에서 받아올 수 있을까?

알아야할 정보가 하나 있다.

CORS (cross-origin resourse sharing)

기본적으로 브라우저는 바깥 source들에 request하는 것이 제한되어 있다.

이를 허용하기 위해서 도메인, 서브도메인, 프로토콜, 포트가 다른 곳에 요청을 보내는 것을 Cross-Origin-Request 라고 하고 이를 위해서는 리모트 오리진에서 전송받은 특별한 헤더가 필요하죠.

이러한 정책 자체를 CORS라고 부릅니다.

CORS는 두가지 종류로 구분됩니다.

  1. 안전한 요청
  • 모든 조건을 만족해야 합니다.

안전한 메서드

GET 이나 POST, HEAD를 사용한 요청

안전한 헤더

Accept
Accept-Language
Content-Language
값이 application/x-www-form-urlencoded이나 multipart/form-data, text/plain인 Content-Type

우리는 Origin이라는 헤더를 요청에 추가하여 크로스 오리진 요청을 보냅니다.

서버는 이 요청의 Origin을 검사하고, 요청을 받아들이기로 동의한 상태라면 특별한 헤더 Access-Control-Allow-Origin을 응답에 추가합니다.

GET /request
Host: anywhere.com
Origin: https://javascript.info


안전한 응답 헤더는 다음과 같습니다.

Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma

하지만 안전한 요청만 있지 않습니다.

안전하지 않은 요청

GET POST 이외에 PATCH, DELETE 등 어떤 메서드도 요청에 포함될 수 있습니다.

이때 서버에 본 요청을 바로 보내는 것이 아니라 preflight 라는 사전 요청을 서버에 보내서 권한이 있는지를 확인합니다.

preflight요청은 OPTIONS 메서드를 사용하고 두 헤더가 함께 들어가며, 본문은 비어있습니다.

Access-Control-Request-Method 헤더 – 안전하지 않은 요청에서 사용하는 메서드 정보가 담겨있습니다.
Access-Control-Request-Headers 헤더 – 안전하지 않은 요청에서 사용하는 헤더 목록이 담겨있습니다. 각 헤더는 쉼표로 구분됩니다.

이때 허용하기로 협의하였었다면 서버는 본문이 비어있고 상태 코드가 200인 응답을 다음과 같은 헤더와 함께 브라우저로 보냅니다.

Access-Control-Allow-Origin – *이나 요청을 보낸 오리진 이어야 합니다(예: https://javascript.info)
Access-Control-Allow-Methods – 허용된 메서드 정보가 담겨있습니다.
Access-Control-Allow-Headers – 허용된 헤더 목록이 담겨있습니다.
Access-Control-Max-Age – 퍼미션 체크 여부를 몇 초간 캐싱해 놓을지를 명시합니다. 이렇게 퍼미션 정보를 캐싱해 놓으면 브라우저는 일정 기간 동안 preflight 요청을 생략하고 안전하지 않은 요청을 보낼 수 있습니다.

credential을 포함한 요청

credential이란 HTTP 인증이나 쿠키 같은 자격 증명입니다.

자바스크립트의 fetch() 메서드 내에 credentials: "include" 옵션을 추가하여 서버에 요청합니다.

서버는
Access-Control-Allow-Origin 헤더와 함께 Access-Control-Allow-Credentials: true 헤더를 추가해서 보냅니다.
이때 Access-Control-Allow-Origin 에는 *(전체) 가 들어갈 수 없으며 정확한 오리진 정보만 명시되어야 합니다.

Fetch()

위의 cors를 js로 이용하는 방법은 다음과 같다.

fetch('url.url.com/api', {
  mode: 'cors'
});

간단하다. 저 url은 무엇인가?

api document에 적혀있는 url이다. 저 url을 통해서 자원으로 이동하여 api를 사용하는 것이다.
여기서 자원의 위치를 endpoint라고 한다.

여기서 알아야 하는 점은 데이터를 받아올 때 데이터가 다 로드가 안 됐는데 탐색할 수 있기 때문에 무조건 비동기적으로 데이터를 받아야 한다는 것이다

실습

적용해야 내것이 된다. 가보자.

  1. giphy는 gif를 랜덤으로 꺼내주는 api를 가지고 있다. 로그인을 한 후 아래의 endpoint를 이용해보겠다.
  1. 로그인해서 얻은 api_key를 이용해 url을 구성하고 fetch는 promise를 갖고 있으므로 .then으로 resolve되는 response를 받아준다.

    (function start() {
      const img = document.querySelector("img");
      fetch("https://api.giphy.com/v1/gifs/trending?api_key=내에이피아이키", {
        mode: "cors",
      })
        .then((response)=>console.log(response.json()))
    })();
  2. 처음 then의 response는 promise가 나오는 것을 확인할 수 있다.

  3. .then을 한번 더 이용하여 리턴되는 promise의 resolve를 받아준다.

    (function start() {
      const img = document.querySelector("img");
      fetch("https://api.giphy.com/v1/gifs/trending?api_key=내에이피아이키", {
        mode: "cors",
      })
        .then((response)=>response.json())
        .then((response)=>console.log(response));
    })();
  4. 원하는 데이터를 찾기 위해서는 object안에 들어 있는 걸 찾아서 가져와야 한다.

    (function start() {
      const img = document.querySelector("img");
      fetch(
        "https://api.giphy.com/v1/gifs/trending?api_key=내에이피아이키",
        {
          mode: "cors",
        },
      ).then((response) => response.json()).then((response)=>{img.src=response.data[0].images.original.url});
    })();
  5. 덤덤하게 말하고 있지만 이거 되고 춤춤

profile
https://github.com/codefug

0개의 댓글