Nextjs와 기본 인증 (accessToken, refreshToken)
2024. 11. 21. 17:54ㆍ컴퓨터언어/React JS
728x90
반응형
1. 인증 API 관리 클래스 설계
class ApiClient {
constructor(baseURL) {
this.baseURL = baseURL;
}
// 기본 API 요청 메서드
async request(endpoint, options = {}) {
const url = `${this.baseURL}${endpoint}`;
const response = await fetch(url, {
...options,
credentials: 'include', // 쿠키 포함
});
if (response.status === 401) {
// AccessToken 만료: RefreshToken으로 갱신 시도
const refreshed = await this.refreshAccessToken();
if (refreshed) {
return this.request(endpoint, options); // 원래 요청 재시도
} else {
throw new Error('Authentication failed. Please log in again.');
}
}
return response;
}
// AccessToken 갱신 메서드
async refreshAccessToken() {
const response = await fetch(`${this.baseURL}/auth/refresh`, {
method: 'POST',
credentials: 'include', // RefreshToken 쿠키 포함
});
if (response.ok) {
return true; // 새 AccessToken 발급 성공
}
return false; // RefreshToken 만료 또는 실패
}
}
export const apiClient = new ApiClient(process.env.NEXT_PUBLIC_API_BASE_URL);
2-1. 서버 컴포넌트에서 cookies 객체로 API 호출
import { apiClient } from '../../utils/apiClient';
export default async function DashboardPage() {
let data;
try {
const response = await apiClient.request('/dashboard', { method: 'GET' });
data = await response.json();
} catch (error) {
console.error('Failed to fetch dashboard data:', error.message);
data = null;
}
return (
<div>
<h1>Dashboard</h1>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
}
2-2. 클라이언트 컴포넌트에서 API 호출
쿠키는 브라우저가 자동으로 처리하므로, credentials: 'include'만 추가하면 된다.
'use client';
import { useEffect, useState } from 'react';
import { apiClient } from '../../utils/apiClient';
export default function ClientDashboard() {
const [data, setData] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await apiClient.request('/dashboard', { method: 'GET' });
const json = await response.json();
setData(json);
} catch (error) {
console.error('Error fetching dashboard data:', error.message);
}
};
fetchData();
}, []);
return (
<div>
<h1>Client Dashboard</h1>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
}
3. 인증 관련 서버 라우트
app/api/auth/refresh/route.ts
import { NextResponse } from 'next/server';
export async function POST(request) {
// RefreshToken 확인 및 AccessToken 갱신
const newAccessToken = 'new-access-token'; // 실제 로직 필요
const response = NextResponse.json({ success: true });
response.cookies.set('accessToken', newAccessToken, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'strict',
path: '/',
maxAge: 60 * 15, // 15분
});
return response;
}
app/api/auth/login/route.ts
import { NextResponse } from 'next/server';
export async function POST(request) {
const { email, password } = await request.json();
// 로그인 검증 후 토큰 발급
const accessToken = 'access-token';
const refreshToken = 'refresh-token';
const response = NextResponse.json({ success: true });
// AccessToken 설정
response.cookies.set('accessToken', accessToken, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'strict',
path: '/',
maxAge: 60 * 15, // 15분
});
// RefreshToken 설정
response.cookies.set('refreshToken', refreshToken, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'strict',
path: '/',
maxAge: 60 * 60 * 24 * 7, // 7일
});
return response;
}
환경변수 설정
NEXT_PUBLIC_API_BASE_URL=https://your-api-url.com
728x90
반응형
'컴퓨터언어 > React JS' 카테고리의 다른 글
react hooks의 등장으로 거의 대체된 render props 방식 (1) | 2024.11.26 |
---|---|
iron-session과 next-auth (1) | 2024.11.25 |
타입스크립트 as와 satisfies 비교 (0) | 2024.11.20 |
React로 타이머 hooks 간단히 개발하기 (0) | 2024.11.18 |
useEffect === componentWillUnMount || componentDidMount || componentDidUpdate (0) | 2020.09.09 |