APP練習-Spotify API (2) PKCE 授權登入

Huei
彼得潘的 Swift iOS / Flutter App 開發教室
6 min readJan 10, 2021

透過 Spotify API 的授權流程,取得使用者授權,給予應用程式訪問使用者資訊的權限,實現登入功能。

接續前一篇 Spotify API 授權機制,此篇將針對官方推薦使用 PKCE 授權流程進行練習。PKCE (Proof Key for Code Exchange) 是 OAuth 2.0 協議裡的其中一種規格:

This specification describes the attack as well as a technique to mitigate against the threat through the use of Proof Key for Code Exchange (PKCE, pronounced "pixy"). 來源:RFC7636

其目的是防止在認證碼授權的過程中,當第三方攔截取得授權碼,搶先向 Server 交換 token,如下圖流程中的 4~6 所示:

認證碼攔截示意,圖片來源:https://www.authlete.com/developers/pkce/
PKCE Protocol Flow

所以 PKCE 的規格中,增加code_verifier (code_challenge) 參數檢核,確保請求方的來源一致,達到無需使用 client_secret 也能完成授權。雖然流程變得繁瑣但也是最安全的一種模式。

接著,參考 Spotify 官網上 PKCE Flow 的 API 規格,取得 access_token:

1. 取得授權碼 code
curl --request 'POST https://accounts.spotify.com/authorize?response_type=code&client_id=77e602fc63fa4b96acff255ed33428d3&redirect_uri=http%3A%2F%2Flocalhost&scope=user-follow-modify&state=e21392da45dbf4&code_challenge=KADwyz1X~HIdcAG20lnXitK6k51xBP4pEMEZHmCneHD1JhrcHjE1P3yU_NjhBz4TdhV6acGo16PCd10xLwMJJ4uCutQZHw&code_challenge_method=S256'
  • client_id=CLIENT_ID
  • response_type=code,表示希望接收到 Authorization Code
  • redirect_uri=REDIRECT_URI ,認證後重新跳轉的 uri
  • scope=user-follow-modify,希望訪問哪些使用者的帳戶資訊 scopes
  • state=e2139…,由 app 產生,提供驗證的一個隨機字串
  • code_challenge_method=S256
  • code_challenge=KADwy…,長度為43~128的隨機字串符號,此字串作為 code_verifier,再依據透過 SHA256 和 base64-encode 運算,取得 code_challenge

若使用者同意授權,畫面將跳轉回指定的 redirect_uri,網址上包含:

  • code 授權碼 Authorization Code
  • state 需驗證和請求中的 state 是否相同
2. 授權碼換取 access_token
curl --request POST 'https://accounts.spotify.com/api/token' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'grant_type=authorization_code' --data-urlencode 'client_id=77e602fc63fa4b96acff255ed33428d3' --data-urlencode 'code=<前一次請求回傳值>' --data-urlencode 'redirect_uri=http%3A%2F%2Flocalhost' --data-urlencode 'code_verifier=<前一步產生的值>'
  • grant_type=authorization_code
  • code=前一次請求取得的回傳值
  • redirect_uri=REDIRECT_URI
  • client_id=CLIENT_ID
  • code_verifier=CODE_VERIFIER,前一次請求產生的 code_verifier

認證成功,可取得 access_token 與 refresh_token,後續訪問資源的 API 都需使用 access_token 作認證,其有效時間為 3600 秒 (1小時),時效過了可透過refresh_token 重新換取 access_token:

3. refresh_token 換取 access_token
curl -H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=refresh_token' \
-d 'refresh_token=bOP-ycJHioNwO9QNqCpaREE4jInOjigq7hESRu3NFOa_XWy5tRLPWtacerPcLRTT3ad_Lsyba3fqidxUnbQZ6s1wIge' \
-d 'client_id=78ddd16c16e43884672d93a4a299bd0a59878fc3' https://accounts.spotify.com/api/token

串接 API 後 Demo 如下 :

Spotify 登入功能

下一篇,將串接 Spotify 提供的 Episodes、Playlists 和 Search API,實現音樂播放功能。

--

--