Skip to content

Commit 5007853

Browse files
authored
Merge pull request #305 from prgrms-web-devcourse-final-project/refactor/useSpotifyAuty
[refactor] useSpotifyAuth 리펙토링
2 parents 67ee4b2 + d7cbb4d commit 5007853

File tree

4 files changed

+48
-34
lines changed

4 files changed

+48
-34
lines changed

src/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { useSheetStore } from './store/sheetStore';
1919
import KaKaoRedirection from '@/components/KaKaoRedirection';
2020
import { useSSE } from '@/hooks/useSSE';
2121
import { useYotube } from '@/hooks/useYoutube';
22-
import { useSpotifyAuth } from '@/hooks/useSpotifyAuth';
22+
import { useSpotifyAuth } from '@/hooks/spotify/useSpotifyAuth';
2323
import UserProfile from '@/pages/user/UserProfile';
2424
import PublicRoute from '@/routes/PublicRoute';
2525

src/components/modalSheet/MusicSearchSheet.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ import defaultImage from '@assets/images/default.png';
77
import axios from 'axios';
88
import { useInfiniteQuery } from '@tanstack/react-query';
99
import LoadingMini from '../loading/LoadingMini';
10+
import { useSpotifyStore } from '@/store/spotifyStore';
1011

1112
function MusicSearchSheet() {
1213
const [searchText, setSearchText] = useState('');
1314
const [query, setQuery] = useState('');
1415
//로컬 스토리지에서 토큰 가져오기
15-
const spotifyAccessToken = localStorage.getItem('spotify_access_token');
16+
const { token } = useSpotifyStore();
1617

1718
// 무한 스크롤 감지용 ref
1819
const loadMoreRef = useRef<HTMLDivElement | null>(null);
@@ -23,7 +24,7 @@ function MusicSearchSheet() {
2324
`https://api.spotify.com/v1/search?q=${encodeURIComponent(query)}&type=track&offset=${pageParam}`,
2425
{
2526
headers: {
26-
Authorization: `Bearer ${spotifyAccessToken}`,
27+
Authorization: `Bearer ${token}`,
2728
},
2829
},
2930
);
@@ -82,7 +83,7 @@ function MusicSearchSheet() {
8283

8384
//음악 리스트 렌더링
8485
const musicListRender = () => {
85-
if (!spotifyAccessToken) {
86+
if (!token) {
8687
return (
8788
<div className="h-[calc(100vh-154px)]">
8889
<InfoMessage text="Spotify 로그인이 필요합니다." />
Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,25 @@
11
import axios from 'axios';
2-
import { useEffect, useState } from 'react';
2+
import { useEffect } from 'react';
33
import { useAuthStore } from '@/store/authStore';
4+
import { useSpotifyStore } from '@/store/spotifyStore';
45

56
const CLIENT_ID = import.meta.env.VITE_SPOTIFY_CLIENT_ID;
67
const CLIENT_SECRET = import.meta.env.VITE_SPOTIFY_CLIENT_SECRET;
78
const TOKEN_URL = 'https://accounts.spotify.com/api/token';
89

910
// 클라이언트 자격 증명 방식 (Client Credentials Flow)
1011
export const useSpotifyAuth = () => {
11-
const [token, setToken] = useState<string | null>(null);
1212
const { isAuthenticated } = useAuthStore();
13-
13+
const { setToken, isTokenValid } = useSpotifyStore();
1414
useEffect(() => {
15-
if (isAuthenticated) {
16-
checkTokenValidity();
17-
} else {
18-
// 인증되지 않은 상태에서는 아무 작업도 하지 않음
19-
setToken(null);
15+
// 로그인 되어있거나 토큰이 유효하지 않는 경우
16+
if (isAuthenticated && !isTokenValid()) {
17+
fetchAccessToken();
2018
}
2119
}, [isAuthenticated]);
2220

2321
// Access Token을 가져오는 함수 (클라이언트 자격 증명 방식)
24-
const getAccessToken = async () => {
22+
const fetchAccessToken = async () => {
2523
const authHeader = `Basic ${btoa(`${CLIENT_ID}:${CLIENT_SECRET}`)}`; // client_id와 client_secret을 Base64로 인코딩
2624

2725
try {
@@ -31,30 +29,11 @@ export const useSpotifyAuth = () => {
3129
'Content-Type': 'application/x-www-form-urlencoded',
3230
},
3331
});
34-
3532
const { access_token, expires_in } = response.data;
36-
37-
// Access Token을 로컬 스토리지에 저장하고 상태를 업데이트
38-
const expiresAt = Date.now() + expires_in * 1000;
39-
localStorage.setItem('spotify_access_token', access_token);
40-
localStorage.setItem('spotify_expires_at', expiresAt.toString());
41-
setToken(access_token);
33+
// useSpotifyStore zustand에 업데이트
34+
setToken(access_token, expires_in);
4235
} catch (error) {
4336
console.error('Error fetching Spotify access token:', error);
4437
}
4538
};
46-
47-
// 토큰 유효성 검사 (만료되었으면 새로 가져옴)
48-
const checkTokenValidity = () => {
49-
const storedToken = localStorage.getItem('spotify_access_token');
50-
const expiresAt = localStorage.getItem('spotify_expires_at');
51-
52-
if (!storedToken || !expiresAt || Date.now() > Number(expiresAt)) {
53-
getAccessToken();
54-
} else {
55-
setToken(storedToken);
56-
}
57-
};
58-
59-
return { token };
6039
};

src/store/spotifyStore.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { create } from 'zustand';
2+
import { persist } from 'zustand/middleware';
3+
4+
interface SpotifyState {
5+
token: string | null;
6+
expiresAt: number | null;
7+
setToken: (token: string, expiresIn: number) => void;
8+
isTokenValid: () => boolean;
9+
clearToken: () => void;
10+
}
11+
12+
export const useSpotifyStore = create(
13+
persist<SpotifyState>(
14+
(set, get) => ({
15+
token: null, // spotify 토큰
16+
expiresAt: null, // 토큰 만료시간
17+
18+
setToken: (token, expiresIn) => {
19+
const expiresAt = Date.now() + expiresIn * 1000;
20+
set({ token, expiresAt });
21+
},
22+
// 토큰 유효성 검사
23+
isTokenValid: () => {
24+
const { token, expiresAt } = get();
25+
return !!token && !!expiresAt && Date.now() < expiresAt;
26+
},
27+
28+
clearToken: () => set({ token: null, expiresAt: null }),
29+
}),
30+
{
31+
name: 'spotify-auth',
32+
},
33+
),
34+
);

0 commit comments

Comments
 (0)