Pokétify_팀프로젝트5_음악추천페이지_tanstackQuery설정_세션accessToken가져와api연결하기

정소현·2024년 10월 13일
0

팀프로젝트

목록 보기
19/50

☘️ 프로젝트명 : Pokétify

☘️ 프로젝트 개요

: 음악과 관련된 서비스를 제공하며 자신만의 플레이리스트를 만들어 커뮤니티페이지에서 유저들과 공유할 수 있는 페이지

☘️ 개발 예정 기능

  • 앨범명, 가수명 등 키워드로 관련된 곡 검색가능
  • 곡을 검색하여 플레이리스트에 추가가능
  • 플레이리스트 공개, 비공개 여부 설정 가능
  • 커뮤니티 사이트에서 플레이리스트를 공유하며 다른 유저들과 소통
  • supabase를 활용한 소셜 로그인 (spotify)

☘️ 개발기간

: 10/10~10/16


🌟 내가 맡은 기능

내가 이번 프로젝트에서 맡은 페이지는 플레이리스트 페이지이다.
현재 개발하려고 하는 기능에는 아래기능들이 있다.

  • 곡을 검색하여 플레이리스트에 추가가능
  • 플레이리스트 공개, 비공개 여부 설정 가능
  • 추천 플레이리스트 조회가능

🌼 Spotify API 사용

SPOTIFY for Developers 링크

  1. 먼저 tanstackquery로 나는 데이터를 fetching해올 거기 떄문에 초기 설정 부터 하였다.

src > app > provider.jsx생성

"use client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ReactNode } from "react";
function makeQueryClient() {
  return new QueryClient({
    defaultOptions: {
      queries: {
        staleTime: 60 * 1000
      }
    }
  });
}

let browserQueryClient: QueryClient | undefined = undefined;
function getQueryClient() {
  if (typeof window === "undefined") {
    // Server: 항상 새로운 queryClient 생성
    return makeQueryClient();
  } else {
    // Browser: 다시 만들지 않고 기존에 이미 client 존재시 해당 client 제공
    if (!browserQueryClient) browserQueryClient = makeQueryClient();
    return browserQueryClient;
  }
}

interface ProviderProps {
  children: ReactNode;
}

export default function Providers({ children }: ProviderProps) {
  // NOTE: suspense boundary 로 로딩 이 잡히지 않는경우, useState 를 사용하여 초기화한다면, clinet 는 유실된다.
  const queryClient = getQueryClient();

  return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;
}

// app > layout.tsx

import type { Metadata } from "next";
import "./globals.css";
import "@/styles/reset.css";
import Providers from "./provider";

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app"
};

export default function RootLayout({
  children
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body>
       <Providers>{children}</Providers>
      </body>
    </html>
  );
}

tanstackQuery의 기본 설정이 다 끝난 후
api들을 불러와서 재생목록을 더하고, 삭제하고, 불러올 수 있는 로직을 작성하였다.


💥 트러블슈팅

🌟 내가 사용하는 api들은 사용자 토큰이 존재해야만 사용을 핧 수 있는 api들이다.

access Token값을 가져와 headers에 넣어줘야 해서 다음과 같은 로직을 작성했었다.

// 공통 헤더 작성 (동적 토큰 사용)
const getHeaders = (accessToken: string | null | undefined) => ({
  Authorization: `Bearer ${accessToken}`
});
// 데이터 불러오기
export const fetchPlaylist = async (playlistId: string) => {
  const { data } = await supabase.auth.getSession();

  const accessToken = data.session?.provider_token;
  const res = await fetch(`${BASEURL}/${playlistId}`, {
    method: "GET",
    headers: getHeaders(accessToken)
  });

  if (!res.ok) {
    throw new Error("fetch 실패");
  }
  const playlistData = await res.json();
  console.log(playlistData);
  return playlistData;
};

supabase의 토큰을 가져오는 로직을 작성했음에도 불구하고
계속해서 401 에러가 떴다.


superbase의 provider_token을 사용하는 것이 아닌 spotify에서 제공해주는 accessToken가져오는 법을 참고하였다.
spotify access Token

1.spotify 대시보드 설정에서 앱을 만들고 발급 받은 spotify client Id 와 spotify client secret을 .env.local 에 넣어주고
.env.local

  1. src > utils > getAccessToken.ts
    내가 accessToken을 가져오려고 로직을 작성하는 곳에서 process.env를 이용해 spotify client Id와 spotify client secret을 넣어준다.
const SPOTIFY_CLIENT_ID = process.env.NEXT_PUBLIC_SPOTIFY_CLIENT_ID as string;
const SPOTIFY_CLIENT_SECRET = process.env.NEXT_PUBLIC_SPOTIFY_CLIENT_SECRET as string;
  1. 스포티파이 api 요청을 위해 토큰을 받아오는 로직을 작성한다.
  • 새로운 URL params를 생성할 수 있도록 로직을 작성하고,
  • spotify의 token을 얻어오는 로직을 작성한 후 "POST"요청을 통해 params를 가져온다.
  • 여러 파일 중 access_token만 꺼내주었다.
const getAccessToken = async () => {
  const params = new URLSearchParams({
    grant_type: "client_credentials",
    client_id: SPOTIFY_CLIENT_ID,
    client_secret: SPOTIFY_CLIENT_SECRET
  });

  const res = await fetch("https://accounts.spotify.com/api/token", {
    method: "POST",
    headers: {
      "Content-Type": "application/x-www-form-urlencoded"
    },
    body: params.toString()
  });

  const { access_token } = await res.json();
  return access_token;

0개의 댓글