Skip to content

Instantly share code, notes, and snippets.

@danwood
Last active January 23, 2024 19:45
Show Gist options
  • Save danwood/00a363dd86d9f969a14b962d5debb7b2 to your computer and use it in GitHub Desktop.
Save danwood/00a363dd86d9f969a14b962d5debb7b2 to your computer and use it in GitHub Desktop.
Patch Peter-Schorn/SpotifyAPIExampleApp to use Authorization Code Flow with PKCE, for users of Peter-Schorn/SpotifyAPI
diff -crB -x S SpotifyAPIExampleApp-main/SpotifyAPIExampleApp/Model/Spotify.swift SpotifyAPIExampleApp-PKCE/SpotifyAPIExampleApp/Model/Spotify.swift
*** SpotifyAPIExampleApp-main/SpotifyAPIExampleApp/Model/Spotify.swift Thu Feb 16 22:38:40 2023
--- SpotifyAPIExampleApp-PKCE/SpotifyAPIExampleApp/Model/Spotify.swift Tue Jan 23 11:35:44 2024
***************
*** 22,35 ****
fatalError("Could not find 'CLIENT_ID' in environment variables")
}()
- private static let clientSecret: String = {
- if let clientSecret = ProcessInfo.processInfo
- .environment["CLIENT_SECRET"] {
- return clientSecret
- }
- fatalError("Could not find 'CLIENT_SECRET' in environment variables")
- }()
-
/// The key in the keychain that is used to store the authorization
/// information: "authorizationManager".
let authorizationManagerKey = "authorizationManager"
--- 22,27 ----
***************
*** 39,44 ****
--- 31,39 ----
let loginCallbackURL = URL(
string: "spotify-api-example-app://login-callback"
)!
+
+ let codeVerifier = String.randomURLSafe(length: 128)
+ var codeChallenge: String { String.makeCodeChallenge(codeVerifier: codeVerifier) }
/// A cryptographically-secure random string used to ensure than an incoming
/// redirect from Spotify was the result of a request made by this app, and
***************
*** 78,86 ****
/// An instance of `SpotifyAPI` that you use to make requests to the Spotify
/// web API.
let api = SpotifyAPI(
! authorizationManager: AuthorizationCodeFlowManager(
! clientId: Spotify.clientId,
! clientSecret: Spotify.clientSecret
)
)
--- 73,80 ----
/// An instance of `SpotifyAPI` that you use to make requests to the Spotify
/// web API.
let api = SpotifyAPI(
! authorizationManager: AuthorizationCodeFlowPKCEManager(
! clientId: Spotify.clientId
)
)
***************
*** 116,122 ****
do {
// Try to decode the data.
let authorizationManager = try JSONDecoder().decode(
! AuthorizationCodeFlowManager.self,
from: authManagerData
)
print("found authorization information in keychain")
--- 110,116 ----
do {
// Try to decode the data.
let authorizationManager = try JSONDecoder().decode(
! AuthorizationCodeFlowPKCEManager.self,
from: authManagerData
)
print("found authorization information in keychain")
***************
*** 161,171 ****
let url = self.api.authorizationManager.makeAuthorizationURL(
redirectURI: self.loginCallbackURL,
- showDialog: true,
// This same value **MUST** be provided for the state parameter of
// `authorizationManager.requestAccessAndRefreshTokens(redirectURIWithQuery:state:)`.
// Otherwise, an error will be thrown.
state: self.authorizationState,
scopes: [
.userReadPlaybackState,
.userModifyPlaybackState,
--- 155,165 ----
let url = self.api.authorizationManager.makeAuthorizationURL(
redirectURI: self.loginCallbackURL,
// This same value **MUST** be provided for the state parameter of
// `authorizationManager.requestAccessAndRefreshTokens(redirectURIWithQuery:state:)`.
// Otherwise, an error will be thrown.
+ codeChallenge: codeChallenge,
state: self.authorizationState,
scopes: [
.userReadPlaybackState,
.userModifyPlaybackState,
diff -crB -x S SpotifyAPIExampleApp-main/SpotifyAPIExampleApp/Views/RootView.swift SpotifyAPIExampleApp-PKCE/SpotifyAPIExampleApp/Views/RootView.swift
*** SpotifyAPIExampleApp-main/SpotifyAPIExampleApp/Views/RootView.swift Thu Feb 16 22:38:40 2023
--- SpotifyAPIExampleApp-PKCE/SpotifyAPIExampleApp/Views/RootView.swift Tue Jan 23 11:36:20 2024
***************
*** 63,68 ****
--- 63,71 ----
// refresh tokens.
spotify.api.authorizationManager.requestAccessAndRefreshTokens(
redirectURIWithQuery: url,
+ // Must match the code verifier that was used to generate the
+ // code challenge when creating the authorization URL.
+ codeVerifier: spotify.codeVerifier,
// This value must be the same as the one used to create the
// authorization URL. Otherwise, an error will be thrown.
state: spotify.authorizationState
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment