I'm sure this is a broader question that applies to more than just Reddit, but currently I am attempting to exchange a code for a user access token however I am not understanding how to implement the following steps:
https://github.com/reddit-archive/reddit/wiki/OAuth2#retrieving-the-access-token
If you didn't get an error and the state value checks out,
you may then make a POST request with code to the following URL to retrieve your access token:
https://www.reddit.com/api/v1/access_token
Include the following information in your POST data (NOT as part of the URL)
grant_type=authorization_code&code=CODE&redirect_uri=URI
Okay, so what I did was this:
headers = {
CLIENT_ID: CLIENT_SECRET,
}
r = requests.post(
url="https://www.reddit.com/api/v1/access_token",
data={
"grant_type": "authorization_code",
"code": code,
"redirect_uri": "http://127.0.0.1:5000/callback"
},
headers=headers
)
I think I am failing with the headers, I receive a 429 error, and I don't think I've understood how to arrange the headers correctly as it doesn't clearly explain in the above link.
The "user" is the client_id. The "password" for confidential clients is the client_secret. The "password" for non-confidential clients (installed apps) is an empty string.
CLIENT_ID and CLIENT_SECRET are obviously variables, and they are my Reddit App dev credentials.
EDIT:
I came up with this, it's gross but it seems to work
headers = {
"User-Agent": "MyApp v1.0",
"Authorization": "Basic " + str(base64.b64encode(str.encode(f"{CLIENT_ID}:{CLIENT_SECRET}")))[2:-1],
}
Is there a cleaner way to write that?
Final answer, using an inbuilt method in Python's request:
client_auth = requests.auth.HTTPBasicAuth(CLIENT_ID, CLIENT_SECRET)
r = requests.post(
url="https://www.example.com/api/v1/access_token",
auth=client_auth,
data={
"grant_type": "authorization_code",
"code": code,
"redirect_uri": "http://127.0.0.1:5000/callback"
},
headers={
"User-Agent": "MyApp v1.0",
}
)
Related
I've been trying to connect my Spotify account using the requests module and I came across a problem
later on I tried to manipulate it on my Python code
import requests
URL = 'https://accounts.spotify.com/login/password'
payload = {
"username": "example#gmail.com",
"password": "123456",
"remember" : True
}
response = requests.post(URL , json=payload)
print(response.status_code)
OUTPUT : 415
what went wrong ?
I don't think this is how you should interact with Spotify from code.
It has an API and you should use tokens for authentication or anything else from password.
Anyway you can try setting the correct media type when making the request:
URL = 'https://accounts.spotify.com/login/password'
payload = {
"username": "example#gmail.com",
"password": "123456",
"remember" : True
}
headers = { 'Content-Type':'application/x-www-form-urlencoded' }
response = requests.post(URL , json=payload, headers=headers)
you cannot use this url to send post request as it has "recaptchaToken" which you need pass in your payload which is getting generated dynamically. Hence it is not a good idea to use this approach.
Instead you can use API to achieve the same.
https://github.com/plamere/spotipy
I'm trying to get accessToken from Xero
This is their instruction:
https://developer.xero.com/documentation/guides/oauth2/auth-flow/#3-exchange-the-code
POST https://identity.xero.com/connect/token
authorization: "Basic " + base64encode(client_id + ":" + client_secret)
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=xxxxxx
&redirect_uri=https://myapp.com/redirect
This is how I do it:
tokenb4 = "{0}:{1}".format(CLIENT_ID, CLIENT_SECRET)
basic_token = base64.urlsafe_b64encode(tokenb4.encode()).decode()
response = requests.post(
"https://identity.xero.com/connect/token",
headers={
"Authorization": "Basic {0}".format(basic_token),
"Content-Type": "application/x-www-form-urlencoded"
},
params="grant_type=authorization_code \
&code=MYCODE \
&redirect_uri=https://developer.xero.com/"
)
Now I keep getting error 400
{"error":"unsupported_grant_type"}
redirect_uri is the same with the one I leave in the App in Xero demo company.
I've googled some, seems like it's a format issue but I can't see what's wrong with my code.
Much appreciation if anyone could help
ref:Python requests module sends JSON string instead of x-www-form-urlencoded param string
I changed the params to
data={
"grant_type": "authorization_code",
"code": "MYCODE",
"redirect_uri": "https://developer.xero.com/"
}
And it works! Hooray!
I'm trying to integrate Vantiv payment gateway using python language.
But when I request on URL https://w1.mercurycert.net/PaymentsAPI/Credit/Sale with the provided test credentials merchant id: 755847002 and password: xyz it still gives me an error message like:
Unauthorized: Access is denied due to invalid credentials.
I am passing JSON data as provided in the documentation:
card_data = {
"InvoiceNo": "1",
"RefNo": "1",
"Memo": "MPS Example JSON v1.0",
"Purchase": "1.00",
"Frequency": "OneTime",
"RecordNo": "RecordNumberRequested",
"TerminalName": "MPS Terminal",
"ShiftID": "MPS Shift",
"OperatorID": "MPS Operator",
"AcctNo": "4003000123456781",
"ExpDate": "0517",
"Address": "4 Corporate Square",
"Zip": "30329",
"CVVData": "880",
}
headers = {
'Authorization': 'Basic [Wzc1NTg0NzAwMV06W3h5el0=]',
'Content-Type': 'application/json',
}
payment = requests.post(
'https://w1.mercurycert.net/PaymentsAPI/Credit/Sale',
headers=headers,
data=card_data)
When I look at the response variable payment, it still shows that error message.
Can anyone help me on how to overcome this?
Actually, All I needed was to encode "Authorization" header and it worked.
I was using this API at wrong place, API that I used (RESP API) can be used with scanner devices only which can encode data. Instead I needed to use Hosted Checkout API and it worked for me.
I am having trouble with the Jawbone API. When I step through the oauth proess using https://github.com/karthikbgl/python-jawbone-up.git I can successfully receive an authorization code and then get a token.
def access_token(self, code, grant_type='authorization_code'):
'''
Get the access code for a user with a auth code.
'''
params = {
'code' : code,
'client_id' : self.client_id,
'client_secret' : self.client_secret,
'grant_type' : grant_type
}
context = {
'base_url': self.base_url,
'params' : urllib.urlencode(params)
}
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json',
'X-Target-URI': 'https://jawbone.com',
'host': 'jawbone.com'
}
token_url = '{base_url}auth/oauth2/token/?{params}'.format(**context)
res = requests.get(token_url, headers=headers)
return res.json()
However the token I receive is always the same, and when I use it to call the API, I receive the error :
{"meta": {"code": 401, "error_detail": "You must be logged in to perform that action", "error_type": "authentication_error", "message": "Unauthorized"}, "data": {}}
Additionally, if I use the module called access_jawbone with this code:
params = urllib.urlencode({
'email': username,
'pwd': password,
'service': 'nudge'
})
tokenresponse = urllib2.urlopen(url, params)
I get a valid token that I can access the API with.
Does anyone know why the oauth token provided is not working
The below question seems to address the same problem, but I do not understand the answer or how to resolve my problem.
Jawbone UP API oAuth and Access Tokens
I had the same issue. I think that this answer is what is happening:
https://stackoverflow.com/a/32984287/1732987
To get around it, I had to log out of all Jawbone stuff in by browser, remove the access token from my new application database, and start the sign in process from a clean slate.
I am trying to send a request to Linkedin's rest share api. I have been receiving this error message:
{
"errorCode": 0,
"message": "Can not parse JSON share document.\nRequest body:\n\nError:\nnull",
"requestId": "ETX9XFEI7N",
"status": 400,
"timestamp": 1437910620120
}
The request is send through the following python code:
import requests,json
auth_token = "some auth token"
url = "https://api.linkedin.com/v1/people/~/shares?format=json&oauth2_access_token="+auth_token
headers = {'content-type': 'application/x-www-form-urlencoded','x-li-format':'json'}
data = {
"comment":"Check out developer.linkedin.com!",
"content":{
"title": "LinkedIn Developers Resources",
"description": "Leverage LinkedIn's APIs to maximize engagement",
"submitted-url": "https://developer.linkedin.com",
"submitted-image-url": "https://example.com/logo.png"
},
"visibility":{
"code": "anyone"
}
}
response = requests.post( url , json= data , headers=headers )
return HttpResponse( response )
I made sure that I followed all the instructions in their documentation and can't find the mistake I am making.
Note: i have tried json=data and data=data both are not working
Remove content-type from the headers dictionary.
requests sets the correct Content-Type when using the json keyword argument.
You have three basic problems:
Please read the documentation on oauth2; because you are not passing in the token correctly.
The share URL does not take a oauth2_token argument.
You have the wrong content-type header.