인터셉터는 ✈️
공항 검색대의 역할을 한다
우리는 해외로 갈 때,
출국 시에 가방 검사를 통해서 위험한 물건을 체크하고
입국 시에도 다시 한번 물건을 체크한다
출국 시, 공항 검색대에서는 먼저 승객의 정보를 확인한다.
위와 같은 기본 정보를 체크한다
이 과정은 리액트에서는
서버에 요청을 보내기 전에 체크를 해주는 것과 동일과정이다
토큰을 확인하고 이를 통해 로그인 여부를 체크해준다입국 시, 공항 검색대에서는 위험 승객을 미리 거른다
응답 인터셉터 는 서버에서 응답을 받을때,
문제를 확인하거나 필요한 정보를 뽑아내준다
✈️공항검색대가 없으면
항공사고가 많을거다 (각종 위법사항, 위험물건 소지 등등)
인터셉터는
미리 각종 문제를 검사해서 문제가 없도록 도와주는
*
중간 다리역할을 해준다 *
또한,
모든 검색을 한군데에서 모아서 하니까
각각의 요청마다 검사를 진행 할 필요없어서
코드가 깔끔해지는 장점이 있다
리액트에서는 주로 Axios와 함께 쓴다
- 서버로 데이터를 보내기 전에 확인 및 수정 작업
// 기본설정
import axios from "axios";
const apiClient = axios.create({
baseURL: "기본 설정 URL",
headers: { "Content-Type": "application/json" },
})
### 👀 header 가 뭐야?
>헤더는 서버와 소통 할 때 보내는 `추가 정보`이다
편지 봉투에 쓰는 정보와 같은 거다
- Content-Type = 보내는 데이터 종류를 서버에 알려준다
(서버에 데이터가 JSON 형식이라고 알려주는 거다)
```js
headers: { "Content-Type": "application/json" }headers: { Authorization: "Bearer YOUR_TOKEN" }
여기서 데이터 형식에는JSON / HTML Form / XML 등등이 있어
인스턴스를 생성했으면
이제 서버로 요청을 보내기 전에 실행하는
요청 인터셉터를 추가해야 해
*여기서는 주로 토큰추가, 데이터 검사, 로그 출력 등의 작업을 처리해 *
apiClient.interceptors.request.use(
(config) => {
토큰 설정 !
}
)
토큰 설정법은 크게
로컬스토리지/쿠키방법이 있다
로컬스토리지 ??
브라우저에 영구적으로 데이터를 저장하는 공간이야
브라우저에만 저장이 되고, 서버로 자동 전송되지 않아
서버로 보내려면 직접 요청을 해야해
장점으로는 저장 방법이 간단하고 직관적이라는 점이 있어
그리고 5MB 저장가능으로, 쿠키에 비해 많은 데이터를 저장해
단점으로는 보안에 취약한 점이 있어
그 이유는 개발자 도구를 통해 접근이 가능해
그리고 악성 스크립트에 의해 탈취될 가능성이 있어
// 토큰 저장
localStorage.setItem('token', 'your_jwt_token');
// 토큰 가져오기
const token = localStorage.getItem('token');
📍 로컬스토리지를 인터셉터로 사용해보기
apuClient.interceptors.request.user(
(config) => {
const token = localStorage.getItem("token");
if (token) {
config.headers.Authorization = `Bearer ${token}`
// 헤더에 토큰 추가
}
return config;
},
(error) => {
return Promise.reject(error);
}
)쿠키 ??
*쿠키의 특징으로는
*- 브라우저에 저장해 그리고 웹사이트 방문 할 때 자동으로 꺼내
= 모든 요청마다 서버에 자동으로 전송돼
(그래서 네트워크 트래픽이 늘어나는 단점이 있어)
세션 쿠키 라고 불러쿠키의 단점은
쿠키의 단점인 XSS 공격을 방어하기 위해httpOnly 옵션을 설정해서 자바스크립트로 접근할 수 없게 만들수 있어
apiClient.interceptors.request.use(
(config) => {
const cookies = document.cookie.split("; ").reduce((acc, cookie) => {
const [key, value] = cookie.split("=");
acc[key] = value;
return acc;
}, {});
const accessToken = cookies.accessToken; // 객체에서 바로 가져오기
if (accessToken) {
config.headers.Authorization = `Bearer ${accessToken}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
📕 1. 브라우저에서 쿠키에 접근
const cookies = doucument.cookie;
이 때 쿠키를 콘솔창에 찍어보면
access토큰 등 다양한 값을 확인 할 수 있다
accessToken=abc123; refreshToken=xyz789; theme=light
이거는 실제 어세스 토큰을 반환해준 쿠키를 콘솔창에 찍은 결과이다
'accessToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjQwNSwiaWF0IjoxNzM3MjEzNTE3LCJleHAiOjE3MzcyMjA3MTd9.0XkIKOspymdlJuPmpi5-plRSBsoqwBzpO6_2UR0703c'
📙 2. 한줄로 나온 값을 ;기준으로 나누어 배열로 만들기
doucument.cookie.split("; ")
// 결과값
[
"accessToken=abc123",
"refreshToken=xyz789",
"theme=dark"
]
📒 3. 배열을 키와 값으로 나눠서 객체로 반환
cookies.reduce((acc, cookie) => {
const [key, value] = cookie.split("=");
// '='로 key와 value 분리
acc[key] = value; // 객체에 키-값 추가
return acc;
}, {});
// 결과값
{
accessToken: "abc123",
refreshToken: "xyz789",
theme: "dark"
}
📗 4. 뽑은 객체에서 accessToken 뽑아서 저장
const accessToken = cookie.accessToken;
// 결과값
"abc123"
📘 5. 받아온 값을 헤더에 추가
if (accessToken) {
config.headers.Authorization = `Bearer ${accessToken}`;
}
🎯 6. 수정된 config 객체 반환
return config
config 객체는
Axios에서 요청을 보낼 때 필요한
URL, 메서드, 헤더 등을 포함하고 있는 객체야
만약 클라이언트가 get요청을 보냈고
이 요청이 인터셉터를 거치면
아래와 같은 config 객체를 가지게 돼
{
baseURL: 'https://example.com/api', // API 기본 URL
url: '/users', // 요청 경로
method: 'get', // 요청 메서드
headers: { // 요청 헤더
Authorization: 'Bearer abc123' // 요청 인터셉터에서 추가한 토큰
},
timeout: 0, // 요청 제한 시간 (기본값: 제한 없음)
withCredentials: false, // 쿠키 포함 여부
}
그리고 만약 POST 요청이라면
post요청의 body 값이config객체에 data값이 추가가 되서 저장돼
{
baseURL: 'https://example.com/api', // Axios 인스턴스의 기본 URL
url: '/login', // 요청 경로
method: 'post', // 요청 메서드
headers: { // 요청 헤더
'Content-Type': 'application/json', // 요청 데이터 형식
Authorization: 'Bearer abc123' // 인터셉터에서 추가한 토큰 (선택적)
},
data: { // 요청 데이터 (body)
username: 'user123',
password: 'password123'
},
timeout: 0, // 요청 제한 시간 (기본값: 제한 없음)
withCredentials: false // 쿠키 포함 여부
}
위에서 쿠키의 단점인 XSS 공격을 방지하기 위해 httpOnly옵션을 사용한다고 했어
여기서 XSS 공격이란
이를 방지하기위해서
예시를 들어보면
보통 아파트 현관은
출입할 때 마다 비밀번호를 입력해야 해(쿠키)
근데 블루투스를 사용한 자동 출입기능을 사용하면
출입할 때 비밀번호를 누르지 않고 접근만 해도 자동으로 문이 열리는거랑 같은 거야
그런데 이 옵션은 클라이언트 측이 아닌 서버가 정하는 규칙이야
그래서 서버코드에 접근 할 수 없는 프론트엔드라면
주어진 설정 그래도 써야돼 ㅎ;
이 옵션은 브라우저가 서버와 통신할 때
쿠키, 인증정보등을 요청에 포함해서 보낼지 말지를 정하는 옵션이야
이 옵션이 필요한 이유는CORS환경 때문인데
CORS환경에서는 다른 도메인으로 요청을 보내면,
기본적으로 쿠키랑 인증정보를 빼고 보내게 설정되있어!
이때 withCredentials: true 옵션을 사용하면
다른 도메인으로 요청을 보내도
쿠키랑 인증정보가 같이 날라가
예시를 들어보면
클라이언트 주소는 http://naver.com
서버 주소는 http://api.movie.com
으로 다른 도메인이야
그럼 클라이언트 측에서 withCredentials옵션을 true로 변경해서 요청을 보내줘야해
axios.get('https://example.com/api', {
withCredentials: true,
});
하지만 두 도메인이 같다면 withCredentials 옵션은 필요없어져!