Spotify에서 스트리밍 어플을 이용하여 음악을 듣고 있는데, 매년 말에 그동안 들었던 음악 연말 결산을 해준다. 근데 꼭 연말까지 기다리지 않고 언제든 내가 지금 어떤 음악을 많이 듣는지, 어떤 아티스트의 음악을 많이 듣는지 구경하면 재밌을 것 같다고 생각했다. spotify api를 사용해서 한 달, 6개월 그리고 전체 기간의 많이 들은 음악과 많이 들은 아티스트를 5순위까지 보여주는 간단한 SPA를 만들었다.
프론트 깃헙: Track Your Music
백엔드 깃헙: TYM server
로그인
Top Artists
Top Tracks
Spotify web으로 이동
개인적으로 spotify api를 꼭 써보고 싶었고, 이렇게 소소하지만 미니 프로젝트로 만들어봐서 괴로웠지만 즐거웠다.
괴로웠던 이유는 spotify 소셜 로그인 구현이 나에게 굉장히 힘들었기 때문이다.
사실 이전에도 spotify api를 써보려고 로그인부터 시도했으나, Oauth 2.0개념도 부족하고, 로그인 token은 그냥 로그인 요청하면 발급되는 당연한 거라고만 생각해서 code를 발급받고 code로 access_token을 요청하는 과정이 설명된 공식 문서 이해가 쉽지 않았다. (안 그래도 처음 보는 내용인데 영어라서 받아들이기 힘들기도 했었다...ㅋㅋ)
유튜브에서 spotify 로그인 구현을 검색해서 나오는 영상 2개를 봤다. (로그인 구현 글 보러가기)
한 영상은 백엔드 없이 로그인을 구현하는 것이었는데, 영상을 보고 따라 구현해 보면서 공식 문서에 설명된 로그인 Flow를 이해하는 데 도움이 되었다. 역시 직접 코드를 짜고 구현해 보는 게 이해하는 데 도움이 많이 된다. 그러나 내가 원하는 데이터를 가져오기 위해서는 유저의 권한 인증 동의가 필요하기 때문에 백엔드까지 구현하는 다른 영상을 하나 더 봤다.
진짜 4~5번은 돌려본 영상...
이 영상을 보고 마침내 spotify api로 소셜 로그인에 성공했다. 그리고 처음 유저 데이터를 가져왔을 때 좀 기뻤다...ㅎㅎ
이 영상에서는 백엔드에서 발급받은 code를 가져와 access_token으로 교환하는 로직을 코드로 구현할 때, spotify web api node라는 라이브러리를 사용한다. 이 영상을 한 3번까지 보니까, 공식 문서에 나와 있는 로그인 flow가 완벽히 이해되었고, Oauth 2.0 개념도 이해되었다.
spotify 소셜 로그인 구현 때 다른 소셜 로그인 방법을 많이 구글링 해봤는데, 카카오 소셜로그인 방법도 스포티파이와 거의 비슷했다. 그리고 3월에 들었던 원티드 프리온보딩 챌린지에서 프론트엔드에서 로그인 관련 강의를 들었던 게 생각나 저장해 뒀던 강의 자료도 다시 읽어보았다.
하지만 이번 미니미니 프로젝트에서 구현하지 못한 건 바로 access_token의 refresh인데, 4~5번 돌려본 영상에서는 access_token의 refresh를 access_token을 발급받는 동시에 만료 시간을 카운트해서 구현한다.
나는 code를 받아오는 Loading 페이지에서 access_token을 요청하고 발급받은 access_token을 로컬 스토리지에 저장, 리덕스 툴킷을 사용하여 전역에 저장 후 /home 루트로 이동한다.
물론 refresh_token과 만료 시간을 함께 로컬 스토리지에 저장해서 /home으로 이동한 후 만료 시간을 카운트하여 token을 refresh 할 수 있겠으나, refresh_token을 다 보이는 로컬에 저장하는 건 보안에 좋지 않을 것 같다는 생각이 들었다. 생각해 봐야겠다.
이번 미니미니 프로젝트에서 구현하는 데 좀 고민을 했던 포인트가, 바로 버튼을 클릭하면 받아오는 데이터가 달라지는 부분이다.
처음에 기본으로 받아오는 데이터는 1 month 기준 Top artists 데이터이다.
근데 옆에 작은 버튼인 6 Month, All Time 버튼을 클릭하면 받아오는 데이터의 기준 범위를 바꿔 준다.
그리고 Top Artists, Top Tracks 버튼을 클릭할 때마다 받아오는 데이터의 카테고리를 바꿔 준다.
작성한 Artists와 Tracks 데이터를 불러오는 api는 다음과 같다.

둘 다 파라미터로 term을 받는다. 버튼을 클릭할 때마다 해당 term 값을 어떻게 넘겨줄까 고민했다.
버튼을 다르게 클릭할 때마다 매번 같은 api를 주면서 호출하는 것은 좀 반복 작업 같았다.
api 호출은 한 곳에서만 하고, 선택된 term button의 값이 바뀔 때마다 api 파라미터로 넘어가는 term 값이 달라지고, 달라진 값으로 api를 호출하는 게 합리적으로 보였다.

스포티파이 소셜 로그인 후 로딩 창에서 Home 페이지로 넘어갈 때, 기본값으로 설정된 term 기간의 Top Artists와 Top Tracks를 받아온다.

term 버튼을 클릭할 때마다 버튼 id에 부여한 term 값을 dispatch 함수를 이용하여 새로운 term 값으로 부여한다.
dispatch로 term 값을 바꿔주고, Home 페이지에 artists와 tracks 데이터를 받아오는 api를 콜하는 useEffect 의존성 배열에 term을 추가해 줬기 때문에 이 api가 선택된 term 값을 가지고 다시 요청된다.
(화면에 렌더링하는 artists와 tracks를 선택하는 로직도 이와 같은 방식이다.)