Xavier L.
Xavier L.

Reputation: 747

Posting to Spotify API for tokens is returning status 415. Am I missing something?

Here is my method for hitting their API for their Authorization Code Flow:

class func obtainAuthTokenPackage(authCode: String) throws
{
    //Create a request
    var request = URLRequest(url: Gimme.theSpotify.urlFor(endpoint: .requestingTokens)) //"https://accounts.spotify.com/api/token"
    request.httpMethod = "POST"

    //Build the header
    let spotifyClientCreds = Gimme.theSpotify.clientID + ":" + Gimme.theSpotify.clientSecret
    let encodedCreds = spotifyClientCreds.data(using: .utf8)!.base64EncodedString()
    request.setValue("Basic \(encodedCreds)", forHTTPHeaderField: "Authorization")
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")

    //Build the body
    var dict = [String:String]()
    dict["grant_type"] = "authorization_code"
    dict["code"] = authCode
    dict["redirect_uri"] = Gimme.theSpotify.redirectURI
    var package = Data()
    do
    {
        package = try JSONSerialization.data(withJSONObject: dict)
    }
    catch 
    {print("oopsie")}
    request.httpBody = package

    //Set up a web transaction
    let transaction = URLSession.shared.dataTask(with: request) {
        (possData, possResp, possErr) in
        if let data = possData
        {
            print(String(data: data, encoding: .utf8)!)
        }
    }
    //Do it
    transaction.resume()
}

The print statement near the bottom produces {"error":"server_error","error_description":"Unexpected status: 415"}

Things I've Tried Already:

Questions I Have:

I appreciate any help, thanx guys.

Upvotes: 0

Views: 1445

Answers (1)

Xavier L.
Xavier L.

Reputation: 747

I DID IT! HAHAHAHAHAHAHAHAHAHA!!!!!!!!!!!

//The endpoint expects form-urlencoded
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")

//Build a string that has client_id, client_secret, grant_type, the code, and the redirect uri
//It has to be in that order (I didn't try any other order, but I've been having this problem for so long, I don't want to risk anything)
//It has to be in the form "key=value&key=value..." (Standard form url encoded format)
var formEncoded = "client_id=\(Gimme.theSpotify.clientID)"
formEncoded.append("&client_secret=\(Gimme.theSpotify.clientSecret)")
formEncoded.append("&grant_type=authorization_code")
formEncoded.append("&code=\(authCode)")
formEncoded.append("&redirect_uri=\(Gimme.theSpotify.redirectURI)")

//Finally convert it into UTF8 data
let bodyData = formEncoded.data(using: .utf8) //Check that this isn't nil, then proceed

//Stick this stuff in the transaction, and it'll be SUCCESSFULLLLL

Questions I had that I am able to answer now:
- This api endpoint https://accounts.spotify.com/api/token application/x-www-form-urlencoded as the Content-Type.
- What I did different: I included client ID and client secret before the grant_type key in the body instead of putting it in the header - I created my http body manually as demonstrated by the code segment above.

In conclusion:
- Nothing really fancy needed
- Spotify API documentation is lacking (but c'mon, who's isn't?)
- I'm relieved

Upvotes: 1

Related Questions