-
Notifications
You must be signed in to change notification settings - Fork 5
httpOnly Cookie, Next.js API route, React query
Won Kim edited this page Nov 4, 2024
·
2 revisions
httpOnly
쿠키를 통해 클라이언트에서 직접 토큰에 접근하지 않고, Next.js API 라우트에서 백엔드 API로 요청을 보내는 방식으로 구현합니다. 이를 통해 클라이언트에서 인증 토큰이 노출되지 않도록 보안을 강화할 수 있습니다.
-
httpOnly
쿠키:accessToken
을httpOnly
쿠키에 저장하면, 쿠키는 클라이언트 JavaScript에서 직접 접근할 수 없습니다. 이 방식은 XSS 공격 방지에 효과적이며, 클라이언트와 서버 간 안전하게 토큰을 전달할 수 있습니다. -
Next.js API 라우트: 클라이언트는 Next.js API 라우트에 요청을 보내면, 서버는 쿠키에 저장된
accessToken
을 사용하여 백엔드 API에 인증된 요청을 보냅니다. Next.js API 라우트는 프록시 역할을 하여 클라이언트가 직접 토큰에 접근할 필요가 없도록 합니다.
다음과 같이 axios
를 사용하여 httpOnly
쿠키에 저장된 accessToken
을 포함해 백엔드 API에 요청합니다.
// app/api/data/route.ts
import { NextRequest, NextResponse } from 'next/server';
import axios from 'axios';
const BACKEND_API_URL = 'https://your-backend-api.com/data';
export async function GET(req: NextRequest) {
try {
// 쿠키에서 accessToken을 가져와 Authorization 헤더로 추가
const accessToken = req.cookies.get('accessToken')?.value;
if (!accessToken) {
return NextResponse.json({ error: '인증 토큰이 없습니다.' }, { status: 401 });
}
// 백엔드 API 호출
const response = await axios.get(BACKEND_API_URL, {
headers: {
Authorization: `Bearer ${accessToken}`, // 백엔드 API에 토큰 포함
},
});
// 백엔드 API로부터 받은 데이터를 클라이언트로 반환
return NextResponse.json(response.data);
} catch (error) {
console.error('백엔드 API 호출 오류:', error);
return NextResponse.json({ error: '백엔드 API 호출에 실패했습니다.' }, { status: 500 });
}
}
위 코드에서는 쿠키에서 accessToken
을 읽어와 백엔드 API 호출 시 Authorization
헤더에 포함시킵니다. 인증이 필요한 API 요청에 대해 서버가 안전하게 accessToken
을 전달하고 클라이언트는 토큰에 직접 접근할 필요가 없으므로 보안이 강화됩니다.
이제 클라이언트 측에서 react-query
를 사용해 Next.js API 라우트를 통해 데이터를 요청하는 훅을 설정합니다.
// src/hooks/useData.ts
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
async function fetchData() {
const response = await axios.get('/api/data', { withCredentials: true });
return response.data;
}
export function useData() {
return useQuery(['data'], fetchData);
}
-
fetchData
함수에서axios.get
요청에withCredentials: true
옵션을 추가하여httpOnly
쿠키가 요청에 자동으로 포함되도록 합니다. -
react-query
는 이 데이터를 캐시하고, 여러 컴포넌트에서 재활용할 수 있습니다.
이제 클라이언트 컴포넌트에서 useData
훅을 사용해 데이터를 가져오고 상태에 따라 화면을 구성합니다.
// src/app/page.tsx
'use client';
import { useData } from '@/hooks/useData';
export default function Page() {
const { data, isLoading, error } = useData();
if (isLoading) return <p>로딩 중...</p>;
if (error) return <p>오류 발생: {error.message}</p>;
return (
<div>
<h1>데이터 목록</h1>
<ul>
{data.map((item: { id: number; name: string }) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
);
}
클라이언트 컴포넌트에서는 Next.js API 라우트를 통해 데이터를 요청하며, react-query
가 로딩, 오류, 성공 상태를 관리합니다.
-
httpOnly 쿠키에
accessToken
을 저장해 보안을 강화하고, 클라이언트에서 토큰에 직접 접근하지 않도록 합니다. - Next.js API 라우트가 프록시 역할을 수행하여 쿠키의 토큰을 읽고 백엔드 API와 통신합니다.
- React query는 클라이언트 측에서 Next.js API 라우트를 통해 데이터를 가져오고 캐시를 관리하여 효율적인 데이터 접근을 제공합니다.
이 구조는 클라이언트에서 직접적으로 accessToken
을 다루지 않아 보안이 강화되는 동시에, react-query
와 Next.js API 라우트를 사용하여 안정적이고 효율적인 데이터 관리를 지원합니다.