Unable to get access token for lyft api - access-token

I am trying to use the lyft developer api. I created a new app to get the client Id and client secret . I am following the steps in https://developer.lyft.com/docs/authentication to get an access token in my python code. But I always get the error, "unauthorized client". Can anyone point out my mistake?
def __init__(self):
self.client_id = 'MY_ID'
self.client_secret = 'MY_SECRET'
# obtain access token
self.token = self.__generate_token__()
# define variables to be used in the request parameters
token_val = 'Bearer '+self.token
self.headers = {'Authorization':token_val}
def __generate_token__(self):
url = 'https://api.lyft.com/oauth/token'
# define request parameters
payload = {"Content-Type": "application/json",
"grant_type": "client_credentials",
"scope": "public"}
# request data
res = requests.post(url,
data = payload,
auth = (self.client_id, self.client_secret))
# extract the token from the response
token = res.json()['access_token']
return token

This is a working example for a Java client
https://github.com/yschimke/oksocial/blob/175bdbf66e312d8bdf79183a140c2c5270329cf2/src/main/java/com/baulsupp/oksocial/services/lyft/LyftClientAuthFlow.java
The main thing that looks wrong, is sending "Content-Type" in the POST data body instead of as a header indicating the format of the data.
It looks like from the requests api that you should be sending "json = payload" instead of "data". But I'm not an expert on this python API.
The curl equivalent of the above java code also works
$ ./oksocial --curl --authorize lyft --client
Authorising Lyft API
Lyft Client Id [***********]:
Lyft Client Secret [********************************]:
curl -X POST -H "Authorization:Basic ******************" -H "Connection:Keep-Alive" -H "User-Agent:okhttp/3.5.0" -H "Host:api.lyft.com" -H "Accept-Encoding:gzip" -H "Content-Length:55" -H "Content-Type:application/json; charset=utf-8" -H "Content-Type:application/json; charset=utf-8" -d '{"grant_type": "client_credentials", "scope": "public"}' https://api.lyft.com/oauth/token

Related

How to correctly pass body to spring rest template?

SOLUTION: The API endpoint to get this specific information is the only one different from all the other ones. Thus I was trying to contact an outdated one.
Everything described in the post works like a charm.
Using kotlin and spring, I want to send a POST request to an API.
This is a curl, generated via postman, that works correctly:
curl --location --request POST 'URL' \
--header 'Content-Type: application/json' \
--data-raw '{
"username":"username",
"password":"password"
}'
However, with spring + rest template using the following code, it seems that the body is not parsed correctly, as the API I am contacting sends me back a 401, that occurs when password/username provided are incorrect/missing.
val body = JwtQuery(getUsername(), getPassword())
return restTemplate.postForObject(url, body, Jwt::class.java)!!
This is the JwtQuery class:
data class JwtQuery (
val username: String,
val password: String
)
Note that getUsername() and getPassword() return the expected value.
What am I doing wrong ?
Edit 1: setting headers
Using:
val body = JwtQuery(getUsername(), getPassword())
val headers = HttpHeaders()
headers.contentType = MediaType.APPLICATION_JSON
val bodyEntity = HttpEntity(body, headers)
return restTemplate.postForObject(url, bodyEntity, Jwt::class.java)!!
Still returns the same error (401)
edit 2: marshaled JwtQuery
val body = JwtQuery(mesProperties.getUsername(), mesProperties.getPassword())
val marshaled = ObjectMapper().writeValueAsString(body)
println(marshaled)
Output:
{"username":"username","password":"password"}

Google cloud text-to-speech : the server responded with a status of 403 ()

I am trying to build a web page which will translate the text into mp3 using google cloud text-to-speech. After lots of search I found using REST API I can request the API to translate the text into mp3.
I am using JQuery and AJAX for the HTTP request.
Problem is that I am requesting the cloud server to translate the text using following data,
"data" : {
"input": {
"text": encodeURIComponent(text)
},
"voice" : {
"languageCode" : "en-US",
"name" : "en-US-Wavenet-A",
},
"audioConfig" : {
"audioEncoding" : "MP3",
}
},
By sending this I'm getting error 403 which clearly says that I do not have access to perform the requested action, in this document
I know without API key and authorization I cannot access the service. So my questions is how can I send my API key and authorizations keys so that I can get the authorization and perform the requested action.
Edit-1
I am sending request to server using following URL,
https://texttospeech.googleapis.com/v1beta1/text:synthesize?further_parameters_goes_here
If anyone want more information I can give it. Any help will be appreciated.
Thank you in advance.
Regards,
Vaibhav M
First you need to get your Google Cloud's API Key from your acount (https://cloud.google.com/docs/authentication/api-keys) and try the code bellow, replacing your-api-key in the script:
$( document ).ready(function() {
// An element to play the speech from Google Cloud
var Sound = (function () {
var df = document.createDocumentFragment();
return function Sound(src) {
var snd = new Audio(src);
df.appendChild(snd); // keep in fragment until finished playing
snd.addEventListener('ended', function () {df.removeChild(snd);});
snd.play();
return snd;
}
}());
// The settings for the Ajax Request
var settings = {
"async": true,
"crossDomain": true,
"url": "https://texttospeech.googleapis.com/v1/text:synthesize",
"method": "POST",
"headers": {
"x-goog-api-key": "**your-api-key**",
"content-type": "application/json",
"cache-control": "no-cache",
},
"processData": false,
"data": "{'input':{'text':'I have added the event to your calendar.'},'voice':{'languageCode':'en-gb','name':'en-GB-Standard-A','ssmlGender':'FEMALE'},'audioConfig':{'audioEncoding':'MP3' }}"
}
// The Ajax Request, on success play the speech
$.ajax(settings).done(function (response) {
console.log(response.audioContent);
var snd = Sound("data:audio/wav;base64," + response.audioContent);
});
});
You need to pass your API key as a header, the header field is "X-Goog-Api-Key". Also make sure you're setting the proper body encoding in the request using the "Content-Type" header, in your case I think it should be "Content-Type: application/json; charset=utf-8". And lastly, I'm think you shouldn't be encoding the text field in the request body.
If you don't have the API key yet, you can follow these steps to get to it
Create a project (or use an existing one) in the Cloud
Console.
Make sure that billing is enabled for your project.
Enable the Text-to-Speech API.
Create an API key.
I'm not familiar with JQuery and AJAX syntax, but you could use this curl command for reference
Curl -H "X-Goog-Api-Key: PUT_YOUR_API_KEY_HERE" \
-H "Content-Type: application/json; charset=utf-8" \
--data "{
'input':{
'text':'Android is a mobile operating system developed by Google,
based on the Linux kernel and designed primarily for
touchscreen mobile devices such as smartphones and tablets.'
},
'voice':{
'languageCode':'en-gb',
'name':'en-GB-Standard-A',
'ssmlGender':'FEMALE'
},
'audioConfig':{
'audioEncoding':'MP3'
}
}" "https://texttospeech.googleapis.com/v1beta1/text:synthesize" > synthesize-text.txt
I found out two possibilities that can help you.
Obtain a Bearer token.
If you installed the Cloud SDK, you can easily get the token with this command: gcloud auth application-default print-access-token. It can be executed in the Cloud Shell too. Just be sure that the default user you are logged in has the appropriate role to access the text-to-speech service. Then, attach the token to the header request, for example a final request can look like this.
curl -H "Authorization: Bearer ya29.GqUB8gVkiMCyl2ZCKEfS8Tb9QmS_LRb1bQP__fIPYbCU.....LUAlCRJU9OpFc_hCzSVUwlAZAhac2aZhoh" \
-H "Content-Type: application/json; charset=utf-8" \
--data "{
'input: {
'text': 'my custom text'
},
'voice' : {
'languageCode' : 'en-US',
'name' : 'en-US-Wavenet-A'
},
'audioConfig' : {
'audioEncoding' : 'MP3'
}
}" "https://texttospeech.googleapis.com/v1beta1/text:synthesize"
This link integrates the request and the command in one step.
Obtain an API key.
An API key is more portable than a token, but it can be used by anyone who possess it. It's recommended to restrict such key to the text-to-speech service. Then, you should use the key in the endpoint URL, for example "https://texttospeech.googleapis.com/v1beta1/text:synthesize?key=AIzaSynAJU-EGnhdDaaXH4NVcc". A complete example looks like the following:
curl -H "Content-Type: application/json; charset=utf-8" \
--data "{
'input':{
'text':'my custom text'
},
'voice':{
'languageCode':'en-gb',
'name':'en-GB-Standard-A',
'ssmlGender':'FEMALE'
},
'audioConfig':{
'audioEncoding':'MP3'
}
}" "https://texttospeech.googleapis.com/v1beta1/text:synthesize?key=AIzaSynAJU-EGnhdDaaXH4NVcc"

Post Request from client With Proper Headers Always return 401- UnAuthorized

Am a newbie to ruby. I am trying to invoke a REST API from ruby code. I have tried the code with both as standalone ruby code and inside a application using sinatra. But am facing same issue every where. Below are the options I have tried.
My Code to Invoke Post API using RestClient. Have modified the data to make it generic
url="https://myapiurl.com/endpointname"
person={"name"=>"Sample Name","age"=>"20"}
headers={
"Content-Type"=>"application/json",
"api-key"=>"ABCDEFGHIJKL"
}
response=RestClient.post url,person.to_json,headers
puts response
I wrote the above block of code in a function and tried calling. But I got response as below
{"status": 401, "error":"Unauthorized Access"}
I tried the same api via postman with below settings and was able to get a proper response from the api.
URL : https://myapiurl.com/endpointname
Headers : Content-Type: application/json, api-key:"ABCDEFGHIJKL"
Body: Raw:application/json: {"name":"Sample Name","age":"20"}
When I tried not passing api-key in the headers via postman I got similar response as I got via ruby code.
Next I tried generating code from postman option. Below is the code that got generated from postman for Ruby(Net::Http).
I removed the post params of cache-control and postman-token from the ruby code and tried running the ruby code. Again I got the same 'Unauthorized' response only !
require 'uri'
require 'net/http'
url = URI("https://myapiurl.com/endpointname")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["api-key"] = 'ABCDEFGHIJKL'
request["cache-control"] = 'no-cache'
request["postman-token"] = 'some value got generated'
request.body = "{\"name\":\"Sample Name\",\"age\":\"20\"}"
response = http.request(request)
puts response.read_body
I suspected is it some IP level issue is blocking hence tried used curl command to hit the api as below. I got proper response from the API.
curl -X POST \
https://myapiurl.com/endpointname \
-H 'content-type: application/json' \
-H 'api-key: ABCDEGHIJKL' \
-d '{"name":"Sample Name","age":"20"}'
I believe that the api-key is not getting passed to the request via the ruby code. Is my way of sending the api-key in headers via ruby code correct?

Microsoft Azure get access token API not working with cURL/Ruby but works with powershell

I am simply trying to get an access token from client id, client secret and tenant ID. Following powershell command works successfully
Invoke-RestMethod -Uri https://login.microsoftonline.com/TENANT/oauth2/token?api-version=1.0 -Method Post -Body #{"grant_type" = "client_credentials"; "resource" = "https://management.core.windows.net/"; "client_id" = "CLIENTID"; "client_secret" = "SECRET" }
But this curl doesn't work
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=client_credentials&resource=https://management.core.windows.net/&client_id=CLIENTID&client_secret=SECRET" "https://login.microsoftonline.com/TENANT/oauth2/token?api-version=1.0"
Neither this ruby script
require 'json'
require 'typhoeus'
url = 'https://login.microsoftonline.com/TENANT/oauth2/token?api-version=1.0'
params = "grant_type=client_credentials&resource=https://management.core.windows.net/&client_id=CLIENTID&client_secret=SECRET"
HEADERS = {
"Content-Type" => "application/x-www-form-urlencoded"
}
resp = Typhoeus::Request.post(url, body: params, headers: HEADERS)
I am following this link. Any clues why neither of curl / ruby works ?
Thanks in advance
I tried to reproduce your issue successfully, and I discovered that the issue was caused by curl without OpenSSL and Typhoeus request without setting ssl_verifypeer: false.
So please follow this to check via curl --version and install openssl libraries on your environment.
Here is my sample code.
require "typhoeus"
url = 'https://login.microsoftonline.com/<tanet-id>/oauth2/token?api-version=1.0'
params = "grant_type=client_credentials&resource=https://management.core.windows.net/&client_id=<client-id>&client_secret=<client-key>"
headers = {
"Content-Type" => "application/x-www-form-urlencoded"
}
request = Typhoeus.post(url, body: params, headers: headers, ssl_verifypeer: false)
puts request.code, request.body
Hope it helps.

Getting Error for jersey client request headers?

I need to set these headers for a REST call via jersey client.
clickatell message send rest call
curl -i \
-X POST \
-H "X-Version: 1" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer Your Authorization Token" \
-H "Accept: application/json" \
My code is:
Client client = Client.create();
WebResource webResource = client.resource("https://api.clickatell.com/rest/message");
ClientResponse response = webResource
.header("Authorization", "Bearer clickATellAuthKey")
.header("X-Version", "1")
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.post(ClientResponse.class, input);
I am getting this error:
{"error":{"code":"001","description":"Authentication
failed","documentation":"http://www.clickatell.com/help/apidocs/error/001.htm"}}
the document says the auth header is not specified. The request is working fine in Postman ( chrome restful client extension) with same headers
Need help.
1) Your headers seem to be going through. If they were not, you would get an error about not setting a version header.
2) The 001 error means your auth token was either not specified, or is incorrect.
3) I suggest that you copy and paste your entire auth token and try again. Watch out for _ or . characters as they are part of the token.
Thanks #whatever_sa there are some improvements required as well in code and also there was an issue with auth key your answer at least make me check the auth key once more. here is the working code
ClientResponse response = webResource.type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)
.header(MessageServices.API_AUTH_HEADER, MessageServices.AUTH_KEY)
.header(MessageServices.API_VERSION_HEADER, MessageServices.API_VERSION)
.post(ClientResponse.class, input);

Resources