Spotify PKCE Authorization using AppAuth fails with "code_verifier was incorrect"

300 Views Asked by At

I have been trying to implement Spotify authorization similarly to Spotify PKCE authorization flow returns "code_verifier was incorrect" but I keep getting "code_verifier was incorrect" on the token request. At first I thought I had an issue generating the challenge like the previously linked post, but I have verified the challenge I am generating with this online tool https://tonyxu-io.github.io/pkce-generator/ and have even tried hardcoding values and still always get the same response. Any ideas as to what may be wrong in my implementation using AppAuth would be much appreciated!

code snippets of challenge/verifier generation and requests:

let codeVerifier = OIDAuthorizationRequest.generateCodeVerifier()
let codeChallenge = challenge(verifier: codeVerifier!)

        let request = OIDAuthorizationRequest(
            configuration: config,
            clientId: Constants.clientID,
            scopes: Constants.scope,
            redirectURL: Constants.redirectURI,
            responseType: OIDResponseTypeCode,
            additionalParameters: [
                "code_challenge_method": "S256",
                "code_challenge": codeChallenge
            ]
        )


        let session = ASWebAuthenticationSession(
            url: request.externalUserAgentRequestURL(),
            callbackURLScheme: Constants.redirectURI.scheme
        ) { [weak self] callbackURL, error in
            if let error = error {
                completion(.failure(error))
                return
            }
            
            guard let callbackURL = callbackURL else {
                let error = NSError(domain: OIDOAuthAuthorizationErrorDomain, code: OIDErrorCodeOAuthToken.RawValue(), userInfo: nil)
                completion(.failure(error))
                return
            }

            let response = OIDTokenRequest(
                configuration: self!.config,
                grantType: OIDGrantTypeAuthorizationCode,
                authorizationCode: callbackURL.queryValue(for: "code"),
                redirectURL: Constants.redirectURI,
                clientID: Constants.clientID,
                clientSecret: Constants.clientSecret,
                scopes: Constants.scope,
                refreshToken: nil,
                codeVerifier: codeVerifier!,
                additionalParameters: nil
            )
    .
    .
    .

using challenge function from https://stackoverflow.com/a/63926351/10006220:

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)
    let challenge = hash.base64EncodedData()
    return String(decoding: challenge, as: UTF8.self)
        .replacingOccurrences(of: "+", with: "-")
        .replacingOccurrences(of: "/", with: "_")
        .replacingOccurrences(of: "=", with: "")
        .trimmingCharacters(in: .whitespaces)
}
1

There are 1 best solutions below

0
ryanknight09 On

So I was sort of facing a similar issue with the pkce flow. I had everything working and then the next day I got the same error. Turns out for me that my verifier kept getting wiped out of local storage after redirect. Looked everyone until I noticed my original url was different that my callback url on my Spotify developer dashboard. Mine is http://localhost:4200/callback but when running the app I was silly and accidentally used http://127.0.0.1:4200/. So at least check you are starting on the correct domain and coming back to the same domain on redirect.