I'm having problems on taking the access token from the oauth2 platform with python.
Currently, that's what I'm using on my post request:
def token(self):
client_id=ID_DO_CLIENTE
client_secret=SECRET_TOKEN
grant_type='client_credentials'
response = requests.post("https://oauth2.googleapis.com/token",
auth=(client_id, client_secret),
data={'grant_type':grant_type,'client_id':client_id,'client_secret':client_secret})
print(response.text)
This specific code is returning the following error:
{
"error": "unsupported_grant_type",
"error_description": "Invalid grant_type: "
}
But I don't think the problem is the grant_type, since I've tried everything I've found online to solve this.
Anyway, if there's any info missing, please let me know. Please help !
A valid request will also need these headers in order to send data in the correct format - I suspect JSON is sent by default, resulting in a malformed request:
Content-Type: application/x-www-form-url-encoded
Authorization: Basic [base 64 encoded client id and secret]
TECHNIQUES
Aim to use the curl tool to get the token first, to ensure the setup is right - as in this article.
Also aim to trace the request via an HTTP proxy tool to ensure that the wire message is being sent correctly.
These techniques will make you more productive when working with OAuth.
CODE
I had a search and this answer seems to use the correct code, though you may be able to send the Authorization header like this:
auth=HTTPBasicAuth('user', 'pass')
This is a sample code for reference:
data = {'grant_type': 'client_credentials'}
requests.post(token_url,
data=data,
auth=(client_id, client_secret))
In the provided sample code, the data part is being sent incorrectly viz:
data={'grant_type':grant_type,'client_id':client_id,'client_secret':client_secret}
I think it should be this:
data={'grant_type':grant_type}
Adding the sample code which I am testing to verify the token generation logic:
client_id = '<value>'
client_secret = '<value>'
# This is optional
scope = '<uri>'
#Token generation step
#If scope is not defined above then remove it from this call
data = {'grant_type': 'client_credentials','scope': scope}
access_token_response = requests.post(token_url, data=data, verify=False, allow_redirects=False, auth=(client_id, client_secret))
print (access_token_response.headers)
print (access_token_response.text)
tokens = json.loads(access_token_response.text)
print ("access token: " + tokens['access_token'])
Related
I am trying to make a POST request to URL , to authenticate myself ( can't share the URL as it is for work). The authentication worked and I got the token access. However , I need to extract the token access header to use it in other function , I don't want to copy the token and paste it .
So , I tried to do this :
response = requests.post(url, data = dic,json={'key':'value'}) # dic is my username and password
token =response.request.headers['AccessToken']
But it is still running , I did not get an error or any output ( I am using Jupyter Notebook)
response = requests.post(url, data = dic) # this one works fine but it does not meet the requirement
Additional clarification :
I am asking the user for (username and password) , then I place them into dic which I pass into the POST request.
Example of Server Response :
{"Result":{"AccessToken":"#####="},"Success":true,"Message":"","ErrorCode":""}
Is there other way to access the AccessToken header of the server response ?
Any ideas?
Thank you
You need to check that there is a header containing an access token in your response.headers dict. You'll probably want to look for an Authorization header, which you'll need to extract the actual token from. In the cases that I'm aware of, that header contents will be
"Authorization": "Bearer encoded-access-token-goes-here"
so you'd check
if "Authorization" in response.headers:
token = response.headers["Authorization"].split()[1]
Example of Server Response :
{"Result":{"AccessToken":"#####="},"Success":true,"Message":"","ErrorCode":""}
Since that is a response, and not a header, you want something like
token = None
try:
token = response.json()["Result"]["AccessToken"]
except KeyError:
print("No token found")
print(response.text)
Heyo. I'm trying to make a small application in my spare time that uses the Spotify API . I have managed to get my program to use oAuth 2 to let a user authorize my app to manipulate their Spotify, but I have run into a problem with a certain endpoint on the Spotify API.
The endpoint I am having trouble with is https://api.spotify.com/v1/me/player/play (here's a link to their docs for the endpoint https://developer.spotify.com/console/put-play/). Whenever I try to make a put request to the endpoint I receive a 400 status code with the message "Malformed json" I get this message even when I copy/paste their own json from the docs, so I don't think it's a problem with how I am formatting my json, besides I have used json before to call other endpoints and they haven't had a problem with my formatting on those calls.
Here is my code:
headers = {"Authorization":"Bearer {}".format(access_token)}
url = 'https://api.spotify.com/v1/me/player/play'
payload = {"context_uri": "spotify:album:5ht7ItJgpBH7W6vJ5BqpPr"}
r = requests.put(url, headers=headers, data=payload)
print(r)
print(r.text)
To clarify, access_token is the access token that I have gotten from their authorization process, and I am using python-requests to make the http requests (Here is the docs for that: https://requests.kennethreitz.org/en/master/)
I am wondering if the problem is due to the fact that Spotify uses colons int their track IDs and colons are also used in JSON? I saw in another thread on here that I should try to add "Content-Type":"application/json" to my headers but that didn't change the outcome at all.
Any help is greatly appreciated, and if you need any more info please let me know. Thank you!
If your payload is a dict use json kwargs in requests lib. data works for string payload. Here you go:
r = requests.put(url, headers=headers, json=payload)
I was making slack api calls through python library slackclient which is a wrapper around slack api. However, for some cases I need to make conventional api calls also with url and get/post method. I was trying to open a direct message channel with another user by my bot. The documentation - https://api.slack.com/methods/im.open says to "Present these parameters as part of an application/x-www-form-urlencoded querystring or POST body. application/json is not currently accepted."
Now in python, I can write,
url = 'https://slack.com/api/im.open'
headers = {'content-type':'x-www-form-urlencoded'}
data = {'token':BOT_TOKEN, 'user':user_id, 'include_locale':'true','return_im':'true'}
r= requests.post(url,headers,data )
print r.text
The message I get is {"ok":false,"error":"not_authed"}
I know the message is "not authed" although I use my bot token and another user id, my hunch is that I'm sending the request in wrong format because I just wrote it some way reading the documentation. I'm not sure how to exactly send these requests.
Any help?
since the Content-Type header is x-www-form-urlencoded sending data in form of dictionary does not work. you can try something like this.
import requests
url = 'https://slack.com/api/im.open'
headers = {'content-type': 'x-www-form-urlencoded'}
data = [
('token', BOT_TOKEN),
('user', user_id),
('include_locale', 'true'),
('return_im', 'true')
]
r = requests.post(url, data, **headers)
print r.text
The second parameter in requests.post is used for data, so in your request you're actually posting the headers dictionary. If you want to use headers you can pass arguments by name.
r= requests.post(url, data, headers=headers)
However this is not necessary in this case because 'x-www-form-urlencoded' is the default when posting form data.
I'm building a chatbot for fun and I cannot send messages to the following API: https://webchat.botframework.com/api/conversations.
After a webchat user send a message, I know the conversation Id and Sender ID. In order to reply, I do the following steps:
First, I retrieve the token with the following code:
response = requests.post(
"https://webchat.botframework.com/api/tokens/conversation",
headers={"Authorization": "BotConnector " + pwdChat,"Content-Type": "application/json"})
data = response.json()
token = data
Then, I would like to send a message to the webchat user with he following code:
requests.post('https://webchat.botframework.com/api/conversations/' + sendersk2 + '/messages/',
headers={"Authorization": "Botconnector " + token, "Content-Type": "application/json"},
json={
"type": "message",
"text": "Hi!"
})
But, I receive an Response [403] error labelled as : "BadArgument:Security token not valid for this conversation"
Any idea of the issue?
There are a couple things that might help.
The endpoint you're using brings back a complex JSON object and you'll need to extract the token property from that.
Alternatively, you can use https://webchat.botframework.com/api/tokens instead, but you'll also need to trim quotes off the end.
Basically, look at the response from your token POST request and ensure you're pulling the token out properly.
Additionally it looks like you are talking to the V1 endpoints. We no longer actively support V1. Please consider upgrading to V3. Thanks.
I am trying to retrieve the access token for the Yahoo API, using the explicit grant flow as described in this document:
https://developer.yahoo.com/oauth2/guide/flows_authcode
Everything is fine until Step 4: Exchange authorization code for Access Token
I wrote the following python script to retrieve the code:
import urllib2
import requests
import json
url = 'https://api.login.yahoo.com/oauth2/get_token'
body = "grant_type=authorization_code&redirect_uri=oob&code=************"
headers = {
'Authorization': 'Basic **************',
'Content-Type': 'application/json'
}
r = requests.post(url, data=body, headers=headers)
print r
Note: I replaced sensitive data with "****"
Now, when I execute the script, I only get the "401" error message.
I am 100% sure that the login credentials are fine, so it seems to be related to the way I make the request. It's also the first time that I am using "requests" in python.
Would be great, if you could give me some feedback on the code, and if I am passing the header and body information correctly. I am especially unsure about the passing of the body. The documentation only states the following:
Sample Request Body: grant_type=authorization_code&redirect_uri=https%3A%2F%2Fwww.example.com&code=abcdef
Change your body variable to a dict, i.e.,
body = {
'grant_type': 'authorization_code',
'redirect_uri': 'oob',
'code': '************',
}
No other changes are needed. Hope it helps.
Tough the problem already solved. But may be other user can still get the same 401 error even if they use correct dict as me. The problem is that the code generated in step 2 in the link can be only use ONCE. And this will get the same 401 error. This took me some time to figure it out. Hope this helps others.