문제 상황
무한 스크롤 기능을 구현하면서 클라이언트 컴포넌트에서 Spotify API에 직접 요청을 보내야 했습니다. 그러나 API 토큰이 서버 측에서만 관리되고 있어 클라이언트에서 API 요청을 할 수 없는 문제가 발생했습니다. 특히 빌드 과정에서 다음과 같은 문제가 있었습니다:
- 로컬 개발 환경에서는 API 라우트 핸들러가 정상적으로 작동했지만,
- 빌드 시에는 로컬 서버가 실행되지 않아 API 라우트 핸들러에 요청을 보낼 수 없었습니다.
해결 방안
이 문제를 해결하기 위해 spotify.api.ts 파일에 다음과 같은 코드를 추가했습니다:
async getAccessToken() {
if (typeof window !== 'undefined') {
const response = await fetch('/api/spotify-token');
const data = await response.json();
this.accessToken = data.token;
this.tokenExpirationTime = Date.now() + 3600 * 1000;
if (!this.accessToken) {
throw new Error("Failed to obtain access token");
}
return this.accessToken;
}
// 서버 사이드 토큰 요청 로직
const auth = Buffer.from(`${this.clientId}:${this.clientSecret}`).toString('base64');
const response = await fetch("https://accounts.spotify.com/api/token", {
method: "POST",
headers: {
Authorization: `Basic ${auth}`,
"Content-Type": "application/x-www-form-urlencoded",
},
body: "grant_type=client_credentials",
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
this.accessToken = data.access_token;
this.tokenExpirationTime = Date.now() + data.expires_in * 1000;
if (!this.accessToken) {
throw new Error("Failed to obtain access token");
}
return this.accessToken;
}
작동 원리
- 클라이언트 사이드 체크: typeof window !== 'undefined'로 코드가 브라우저에서 실행 중인지 확인합니다.
- 클라이언트 사이드 토큰 요청: 브라우저 환경에서는 API 라우트를 통해 토큰을 요청합니다.
- 서버 사이드 토큰 요청: 서버 환경에서는 직접 Spotify API에 토큰을 요청합니다.
- 빌드 시 동작: 빌드 과정에서 window 객체가 없으므로, 서버 사이드 로직이 실행됩니다. 이로 인해 빌드 오류를 방지할 수 있습니다.
학습 포인트
- 환경에 따른 조건부 실행: 클라이언트와 서버 환경에서 각각 다른 로직을 실행하는 방법을 배웠습니다.
- API 토큰 관리의 중요성: 보안을 위해 서버에서 관리하되, 클라이언트에서도 필요시 안전하게 접근할 수 있는 방법을 구현했습니다.
- 빌드 프로세스 이해: Next.js의 빌드 프로세스와 API 라우트의 동작 방식에 대해 더 깊이 이해하게 되었습니다.
- 에러 처리의 중요성: 토큰 획득 실패 시 적절한 에러 처리를 통해 안정성을 높였습니다.
결론
이 경험을 통해 Next.js에서 클라이언트와 서버 로직을 효과적으로 분리하면서도 안전하게 연동하는 방법을 배웠습니다. 특히 무한 스크롤과 같은 클라이언트 사이드 기능 구현 시 API 토큰 관리의 중요성을 깨달았습니다. 이러한 패턴은 보안을 유지하면서도 필요한 기능을 제공하는 우수한 아키텍처라고 생각합니다. 앞으로 다른 API 통합 작업에서도 이 접근 방식을 활용할 수 있을 것 같습니다.
'TIL' 카테고리의 다른 글
TIL - 프로젝트 선정 과정 및 최종 결정 (0) | 2024.07.16 |
---|---|
TIL - 타입스크립트 타입 가드와 타입 좁히기 (0) | 2024.07.15 |
TIL - 효율적인 데이터 Fetching 전략: 벌크 vs 개별 요청 (0) | 2024.07.11 |
TIL - Next.js와 Zustand를 사용한 상태 관리 및 SSR 하이드레이션 (0) | 2024.07.10 |
TIL- 시스템 설계와 Many-to-Many 관계 적용 (0) | 2024.07.09 |