처음 실무를 막 시작했을 때, 새로운 웹사이트를 처음부터 만들어야 했다. 프로젝트를 몇개 해왔지만 이제 실무를 시작한 주니어 개발자였고, 회사에 프론트엔드 개발자는 나 혼자였다. 초반에 많은 시행착오를 겪었었는데, 그 중 하나가 api 요청을 할 때 header에 token을 넣는 것이었다.
간단하고 기본적인 것이지만 처음에는 몇시간을 헤맸었는데, 지금은 어떻게 처리하고 있는지 기록해본다.
일반적으로 클라이언트에서 api 를 호출해서 데이터를 불러오거나 데이터를 보낼때, header에 token을 넣어 요청을 한다.
왜 이렇게 token을 넣어서 api 를 호출해야 할까?
헤더에 token을 넣는 이유
API 요청시 헤더에 token을 넣는 것은 보안을 유지하기 위해서다.
클라이언트에서 허가된 사용자가 api를 호출해야 하는데, 서버는 이를 확인하기 위해 클라이언트에게 token 을 발급한다. 이 토큰은 로그인과 같은 본인인증 과정을 통해 발급받는다.
이 토큰은 보안상의 이유로 일정 시기마다 만료되어 매번 새로운 토큰으로 갱신되며, 클라이언트는 api 를 호출할 때마다 발급받은 토큰을 헤더에 담아서 보내야 한다.
이로써 서버는 api 를 호출한 클라이언트가 허가된 사용자인지 확인할 수 있다. 만약 토큰이 없거나 유효하지 않은 경우, api 서버는 요청을 거부하여 에러를 발생시킨다.
이러한 방식을 통해 토큰으로 인증 및 보안을 유지할 수 있다.
API 요청마다 헤더에 token 넣기
token을 서버에서 받고, 그 토큰을 헤더에 넣어 api 요청이 쉽게 될거라 생각했는데, 생각보다 시행착오를 많이 겪었다.
몇번의 시행착오를 통해 내가 짠 코드는 다음과 같다.
물론 내가 짠 코드보다 더 좋은 코드들이 많이 있고, 현재엔 나도 다른 방식을 사용하고 있지만 이전에 어떻게 header에 토큰을 넣었는지 보여주고 싶다.
1. 로그인 요청의 결과로 받은 access token을 localStorage 에 저장을 하고, api 요청때마다 헤더를 setting 할수 있는 getInstnceATK promise 를 만든다.
import axios, { AxiosInstance } from 'axios';
export const baseURL = process.env.REACT_APP_BASE_URL;
export const getInstanceATK = async(): Promise<AxiosInstance> => {
const instanceATK = axios.create({
baseURL,
headers: {
accept: 'application/json',
Authroization: 'Bearer ' + (await localStorage.getItem('accessToken')),
}
});
return instanceATK;
}
axios.create([config])의 create() 메서드는 axios의 인스턴스를 생성하는 메서드로, 괄호안에 내가 구성한 axios 옵션을 넣어주면 된다. baseUrl, headers, params, adapter 등을 옵션으로 넣을 수 있다.
2. 위에서 만든 promise 객체는 api를 요청을 할때 사용된다.
아래 코드를 보면 getInstanceATK를 호출하여 Axios Instance 를 만들고, 그 객체로 api 호출을 하는 방식이다.
위 코드처럼 만든 api 는 다음과 같이 사용한다.
const getData = async() => {
const {data} = await getResultData(props)
....
}
추가로 이어지는 글로, 지금은 어떤 방식으로 token을 헤더에 넣고 있는지에 대해 포스팅해보겠다.