Reputation: 3723
I need to get an access token from Spotify Web API. Based on this documentation I wrote the following method:
def authorize
grant = Base64.encode64("#{SPOTIFY_KEY}:#{SPOTIFY_SECRET}")
RestClient::Request.execute(
method: :post,
url: 'https://accounts.spotify.com/api/token',
params: {'grant_type' => 'client_credentials'},
headers: {"Authorization" => "Basic #{grant}","Accept" => "*/*; q=0.5, application/json"}
)
end
and the following RSpec test:
it 'authorize' do
obj = SpotifyIntegration.new
response = obj.authorize
myjson = JSON.parse(response.body)
expect(myjson.has_key?('access_token')).to be(true)
expect(myjson.has_key?('token_type')).to be(true)
expect(myjson['token_type']).to eq('bearer')
expect(myjson.has_key?('expires_in')).to be(true)
end
It happens that when I run this test, generating this request (caught with RESTCLIENT_LOG=stdout)
RestClient.post "https://accounts.spotify.com/api/token", "Accept"=>"/; q=0.5, application/json", "Accept-Encoding"=>"gzip, deflate", "Authorization"=>"Basic Y2NmNTI3ODVlZWI1NDVlODk0ZmM2ZTY3YTZhNDM0ZDA6YTQ5MjdlOGFmOWQy\nNGE0OTgyZDRkODI1MmJhZjBkNTI=\n"
I get
=> 400 BadRequest | application/json 131 bytes
And it seems it is really a bad request, because I see no sign of the grant_type => client_credentials
. The documentaions says this is mandadory as a request body parameter.
I believe I am sending this the wrong way, but I don't know how to to it correctly.
I tried to use RestClient#post
instead of RestClient::Request#execute
, doing this:
def authorize
grant = Base64.encode64("#{SPOTIFY_KEY}:#{SPOTIFY_SECRET}")
RestClient.post 'https://accounts.spotify.com/api/token', {'grant_type' => 'client_credentials'}.to_json, {"Authentication" => "Basic #{grant}",content_type: :json, accept: :json}
end
but then I got:
RestClient::UnsupportedMediaType: 415 Unsupported Media Type
How may I send a request body parameter using RestClient
gem?
Upvotes: 2
Views: 1729
Reputation: 15967
The issue is the way Base64 is encoding the string which includes newlines that most OAuth2 providers don't accept. You can do this instead:
grant = Base64.encode64("#{client_id}:#{client_secret}").delete("\n")
resp = RestClient.post('https://accounts.spotify.com/api/token',
{'grant_type' => 'client_credentials'},
{"Authorization" => "Basic #{grant}"})
According to this answer, new lines are added every 60 characters (that is news to me). You can use another method that does not include newlines such as strict_encode
...
grant = Base64.strict_encode64("#{client_id}:#{client_secret}")
Upvotes: 3
Reputation: 1836
It's not exactly the answer you're looking for, but you should definitively take a look at this Ruby Library: rspotify. Spotify Oauthentication is very easy to do with it.
Upvotes: 1