Spotify PKCE yetkilendirme akışı "code_verifier was yanlış" döndürüyor
PKCE kullanarak uygulamamın kimliğini doğrulamak için Spotify API's Authentication Guide'ı takip ediyorum.
Şu an itibariyle, hata ayıklama için önceden hesaplanmış bir meydan okuma ile sahte bir kod doğrulayıcı kullanıyorum . Bu değerler, birden çok çevrimiçi araç ( SHA256 , SHA256 , base64url , base64url ) kullanılarak hesaplandı ve Swift'de yazdığım hashing / kodlama işlevlerinden döndürülen değerlerle eşleşti. Bunları doğrulamak için yukarıdaki bağlantıları kullanmaktan çekinmeyin.
let verifier = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
let challenge = "66d34fba71f8f450f7e45598853e53bfc23bbd129027cbb131a2f4ffd7878cd0"
let challengeBase64URL = "NjZkMzRmYmE3MWY4ZjQ1MGY3ZTQ1NTk4ODUzZTUzYmZjMjNiYmQxMjkwMjdjYmIxMzFhMmY0ZmZkNzg3OGNkMA"
2. adımdaki ilk isteğimi yapmak için ASWebAuthenticationSession kullanıyorum, örneğin:
var components = URLComponents()
components.scheme = "https"
components.host = "accounts.spotify.com"
components.path = "/authorize"
components.queryItems = [
URLQueryItem(name: "client_id", value: SpotifyClientID),
URLQueryItem(name: "response_type", value: "code"),
URLQueryItem(name: "redirect_uri", value: SpotifyRedirectURL.absoluteString),
URLQueryItem(name: "code_challenge_method", value: "S256"),
URLQueryItem(name: "code_challenge", value: challenge),
URLQueryItem(name: "state", value: "testing-state"),
URLQueryItem(name: "scope", value: "user-follow-read")
]
let urlString = components.url!.absoluteString
guard let authURL = URL(string: urlString) else { return }
print(authURL)
let authSession = ASWebAuthenticationSession(url: authURL, callbackURLScheme: callbackScheme, completionHandler: handleLoginResponse)
authSession.presentationContextProvider = self
authSession.prefersEphemeralWebBrowserSession = true
authSession.start()
İçinde handleLoginResponse
, 3. adımdaki yanıtı ayrıştırıyorum ve Alamofire kullanarak 4. adım için ağ talebinde bulunuyorum:
guard let items = URLComponents(string: callbackURL?.absoluteString ?? "").queryItems else { return }
let authCode = items[0].value!
let endpoint = "https://accounts.spotify.com/api/token"
let headers = HTTPHeaders(["Content-Type": "application/x-www-form-urlencoded"])
let parameters: [String: String] = [
"client_id": SpotifyClientID,
"grant_type": "authorization_code",
"code": authCode,
"redirect_uri": SpotifyRedirectURL.absoluteString,
"code_verifier": verifier!
]
AF.request(endpoint,
method: .post,
parameters: parameters,
encoder: URLEncodedFormParameterEncoder.default,
headers: headers
).cURLDescription() { description in
print(description)
}
.responseJSON() { (json) in
print(json)
}
Alamofire, Swift içinden cURL istekleri yapmak için bir arayüz oluşturur ve arama cURLDescription()
, gerçek cURL komutunun tam olarak ne olduğunu görmemi sağlar:
$ curl -v \
-X POST \
-b "__Host-device_id=AQBHyRKdulrPJU6vY5xlua1xKOZBtBZVcrW9IK-X0LQ_MPj5x3N4mZkF4OzgLMdQwviWUxJ2dY6d49d0QpjG0ayFtCfrhwzG5-g" \
-H "User-Agent: SpotifyUserGraph/1.0 (hl999.SpotifyUserGraph; build:1; iOS 14.0.0) Alamofire/5.1.0" \
-H "Accept-Encoding: br;q=1.0, gzip;q=0.9, deflate;q=0.8" \
-H "Accept-Language: en-US;q=1.0, zh-Hans-US;q=0.9, ko-US;q=0.8" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=e11fb810282946569aab8f89e52f78d5&code=AQC3Lm3KDPFCg3mBjSAiXMyvjdn5GvUJCjjCTQzPhAFe5mLntAHcAeiEufXcCv3Jne2qn345MZxBNiCggO-35mn6AAFsjRlm5lPynyC6clWABSzBK1OdWIynTlf0CiyR8vWYeO54GHHEXBSzj6URKWnAiXuxTUV6n1Axra6Oet8FY6-0jwU0CNGMaB91q1JFXlyl5J9JvrRtrP3s2Ef8Xb5A7gcCzqW6RHRzO0--BKiPHFnprK0SitiLxi-md2aaMnS2aHsRTqvc_NfFcuRpFR05WmSm6Gvkk_9trSBqRvVZYuGs-Ap3-ydVGk7BCqNc3lpbh4Jku6W_930fOg9kI__zRA&code_verifier=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&grant_type=authorization_code&redirect_uri=hl999-spotifyusergraph%3A//spotify-login-callback" \
"https://accounts.spotify.com/api/token"
Okuması biraz zor, ancak isteğin doğru yapıldığından oldukça eminim.
Ancak, 4. adımda, bu hata iletisini her zaman sunucudan alıyorum:
error = "invalid_grant";
"error_description" = "code_verifier was incorrect";
Birkaç saat boyunca birçok şeyi denedim ve hala çözemiyorum. Herhangi bir işaret çok takdir edilecektir. Teşekkürler!
Yanıtlar
Sizin sorununuz, SHA hash'in ham baytlarının base64 olması gereken şey olmasıdır. Ayrıca Alamofire ve Spotify PKCE kullanan ve kod sorunuyla ilgili sorun yaşayan bir uygulama üzerinde çalışıyorum. Yaptığım şey, Swift 3 için yazılmış olan ve Swift 5 ile çalışacak şekilde değiştirilen Auth0 belgelerinden bazı kodları kullanmaktı :
import Foundation
import CommonCrypto
func challenge(verifier: String) -> String {
guard let verifierData = verifier.data(using: String.Encoding.utf8) else { return "error" }
var buffer = [UInt8](repeating: 0, count:Int(CC_SHA256_DIGEST_LENGTH))
verifierData.withUnsafeBytes {
CC_SHA256($0.baseAddress, CC_LONG(verifierData.count), &buffer)
}
let hash = Data(_: buffer)
print(hash)
let challenge = hash.base64EncodedData()
return String(decoding: challenge, as: UTF8.self)
.replacingOccurrences(of: "+", with: "-")
.replacingOccurrences(of: "/", with: "_")
.replacingOccurrences(of: "=", with: "")
.trimmingCharacters(in: .whitespaces)
}
print(challenge(verifier: "ExampleVerifier"))
Umarım bu yardımcı olur ve size iyi şanslar!
Bu çevrimiçi PKCE doğrulayıcısını kullandığımda , doğrulayıcı için farklı bir zorlukla karşılaştım, bu yüzden belki aracın size verdiği değerlerle yeniden deneyebilirim.
GENEL GÜVENLİK
Güvenliği kendiniz kodlamanıza gerek kalmaması için AppAuth gibi saygın bir güvenlik kitaplığı kullanırdım. Kitaplıklar olası hatalardan kaçınmamıza yardımcı olur ve gelecekte ücretsiz olarak yeni güvenlik özellikleri alırız.
APPAUTH ENTEGRASYONU
Bu yaklaşımla ilgileniyorsanız, bu adımlar ve kaynaklarım yararlı olabilir:
- AppAuth Örneğini Çalıştırma
- Ardından, Spotify ile çalıştığından emin olmak için yapılandırmanızı güncelleyin
- Gelişmiş AppAuth Örneği , yaygın mobil OAuth sorunlarını aşmak için daha ayrıntılı bazı alanları kapsar
KOD
İşte kütüphaneleri entegre eden bazı Swift kodum var ve düşük seviyeli PKCE işlemeye gerek yok.