Reputation: 747
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:
Changing request.setValue(...
to request.addValue(...
and vice versa doesn't seem to make a difference.
Using application/x-www-form-urlencoded
, changing the http body to "grant_type=authorization_code&code=" + authCode + ...".data(using: .utf8)
.
When I did this, API responds with a message that I need to set the grant type to authorization_code (which tells me their server isn't parsing my http body correctly).
Moving client credentials from the header to the body (using JSON).
Creating my http body using Swift 4's new JSON encoding tools
Requesting using the Rested app (it's like Postman or HTTPRequestor)
Implementing their Implicit Grant Flow with success. But that doesn't give a refresh token and I need it :(.
Sobbing internally so I don't distract people around me
Changing Content-Type
to content-type
Removing the header field that specifies content type
Escaping characters in the redirect-uri
(e.g. replacing colons with %3A, slashes with %2F)
Questions I Have:
Status 415 means unsupported media type, so is the Spotify API expecting application/x-www-form-urlencoded
instead of JSON?
If you can get Spotify's Authorization Code Flow working in your Swift project, what did you do different?
If you use application/x-www-form-urlencoded
, how did you create your http body?
I appreciate any help, thanx guys.
Upvotes: 0
Views: 1445
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