I have a bit of a problem, I have a django application that is using Django OAuth Toolkit and I can't get the access token from the server when using Authorization Code flow. Implicit flow works fine. I haven't find anything regarding my problem on stack so I'm really sorry if this is a duplicate of another question.
I can authorize with this url and get the request come back, if i understand it correctly the request token is past in the code param.
http://mydomain.se/o/authorize?scope=read+write&state=kalle&redirect_uri=mycallbakurls&response_type=code&client_id=myclientid
when i then try to do a post to http://mydomain.se/o/token/
with:
grant_type = authorization_code
code = code from authorize call
client_id = my clientId
client_secret = my client secret
redirect_uri = my callback url
i get "error" : "invalid_grant" back.
Can someone please point me in the right direction what the problem can be?
Best regards Markus
This can happen if the code is expired. They expire pretty quickly by default. You can look up your code in the Django admin under Grants and change the expiration date to far in the future.
I faced the same problem when my client type is confidential rather than public in o/application. Here's how I solved it.
Failed error message is {"error": "invalid_grant"}
curl -X POST -d "client_id=17U5rPQM1HDtF3hR8sIRP6pmzn033EbnwJJ6lNCx& client_secret=D6bSgR8qyIwDl5SyF4kJ0wBJq56NXMUY9LVjD6NZTxnAh4ylTD2YBJxDBaLahpabZMGowWpVTYn6UW8Yq1GB6nAwm7euXZZxXaCxQLKK2KDNrfz4JSavFCKekc1LOCQz&grant_type=authorization_code&code=EaBVzVEjqbsU0GKl5gXK7ArrfsSiTJ&redirect_uri=http%3A%2F%2Flocalhost%2Foauth_client%2F" http://localhost:8080/o/token/
{"error": "invalid_grant"}
Then changed my client type to public and got Success.
curl -X POST -d "client_id=17U5rPQM1HDtF3hR8sIRP6pmzn033EbnwJJ6lNCx&client_secret=D6bSgR8qyIwDl5SyF4kJ0wBJq56NXMUY9LVjD6NZTxnAh4ylTD2YBJxDBaLahpabZMGowWpVTYn6UW8Yq1GB6nAwm7euXZZxXaCxQLKK2KDNrfz4JSavFCKekc1LOCQz&grant_type=authorization_code&code=1ZxQjLN4QbpjaWgbztnOIe3K4bgxKj&redirect_uri=http%3A%2F%2Flocalhost%2Foauth_client%2F" http://localhost:8080/o/token/
{"access_token": "KstIqSnt9Mj4ITmCGRJpTYW3W59nRv", "token_type": "Bearer", "expires_in": 36000, "refresh_token": "uJzJal9YSpirSax6vW2Di43ojRGvRV", "scope": "read write groups"}
Again changed back to Confidential and send my username and password in curl request.
curl -X POST -d "client_id=17U5rPQM1HDtF3hR8sIRP6pmzn033EbnwJJ6lNCx&client_secret=D6bSgR8qyIwDl5SyF4kJ0wBJq56NXMUY9LVjD6NZTxnAh4ylTD2YBJxDBaLahpabZMGowWpVTYn6UW8Yq1GB6nAwm7euXZZxXaCxQLKK2KDNrfz4JSavFCKekc1LOCQz&grant_type=authorization_code&code=UJnq1xfKULOUD0m2Oxb26NYmnuxKMn&redirect_uri=http%3A%2F%2Flocalhost%2Foauth_client%2F" -u'admin:pass' http://localhost:8080/o/token/
{"access_token": "VhMgx59x4PHUPOgSTKMGewsM8JfT58", "token_type": "Bearer", "expires_in": 36000, "refresh_token": "T0BhP1lFvyiS9c5rH6xHqt4uBItAS1", "scope": "read write groups"}
I Found that I can't do the request separately. When I built my own client and tested all worked fine for me.
Check to verify that you set your details correctly. For instance in my case my client_id was wrong.
Related
I was trying to login to roblox account through roblox auth api (https://auth.roblox.com/docs#!/Authentication/post_v2_login) with python request library.
data = {
"ctype": "Username",
"cvalue": "testusername",
"password": "testpassword"
}
response = requests.post("https://auth.roblox.com/v2/login", json=data, headers =get_headers())
But it response with
{"errors":[{"code":2,"message":"You must pass the robot test before logging in.","userFacingMessage":"Something went wrong","fieldData":"{\"dxBlob\":\"Ft9poWGH6MyJP/XR.H0KuG1miZj/UQ47mXaurhf9HAcX8ne+fAxFGsXwMjk+Yn8dsO+7i0R85UhKiKzGnu3TgFWNesUlKXhQ+Ie/ntNEbR807JE8kTdgLoulpu43JPQQlxCU9hZIFryPkU+p+Vymkd2D8o3OW6jdZ1igww0GqLpKUluYHMrF9ULH8oEX3KT5iBDCw3CfVWendM3nAfAgLj42fr8Y9K8z5INY5nscLShCmyw5XlqKCKtctsZTQRsWF0AWueri60GtARaXbLzUQHzobv8XkurBYLY+MNTxdOfi8cEZAyhYhTiseB+qQIZIFNY95rFITHK46qbZwRW11VlziYqXE+HYP1tvkZf886pD+WT9iShBrs15UmEoChGEoJ5sirijiqy2KY5pj2O+hU8LJb5ziG6OaaGg=\",\"unifiedCaptchaId\":\"jgGnfWmwwfhxzGwEH4SVQZ\"}"}]}
how to continue from this step? can I get a captcha image from there response data to solve manually? or what they asking to do?
You need the captcha token.
The payload is supposed to be this
data = {
"ctype": "Username",
"captchaToken": "CaptchaToken",
"cvalue": "testusername",
"password": "testpassword"
}
I don't know what is going on exactly and also don't know this site, but try these:
Turn off your VPN or proxy and then try again.
This site seems to be written with microservices arch, so they may have another API doc that contains what you need.
I hope that this will help you.
I can see you're trying to automate logging into Roblox, The problem here is you haven't solved the captcha. The "robot test" they're referring to here is FunCaptcha that's embed onto the login page. If you'd still like to login, you might have to use captcha solving services to get the captchaToken and then pass it while logging in.
I am very new to APIs (still learning) and I encountered a very weird issue with Python requests library when trying to initiate an OAuth Authentication flow with Client Credentials Grant Type.
For some reason, whenever I used my Python script (with the help of requests library) to send the HTTP request to the authentication endpoint, I always get
Response Status Code: 400
Response Body/Data returned: {"error":"unsupported_grant_type"}
However, if I tried using curl command line tool to send the request, I will get a successful response with status code 200 with the access token in the response body like this:
{'access_token': 'some access token',
'expires_in': 'num_of_seconds',
'token_type': 'Bearer'}
As a matter of fact, if I tried sending the request using Curl command line tool WITHIN my Python Script (with subprocess.Popen function), I can get the response with status code 200 and the access token with no problem.
Now, with that said, here's the Python script that I used to send the request to initiate the OAuth authentication flow:
import requests
import os
import base64
clientCredentialEndpoint = "https://base_url/path/token"
client_id = os.environ.get('CLIENT_ID')
client_secret = os.environ.get('CLIENT_SECRET')
# -- Encode the <client_id:client_secret> string to base64 --
auth_value = f'{client_id}:{client_secret}'
auth_value_bytes = auth_value.encode('ascii')
auth_value_b64 = base64.b64encode(auth_value_bytes).decode('ascii')
queryParams ={
'grant_type':'client_credentials',
'scope':'get_listings_data'
}
headers = {
'Authorization':f'Basic {auth_value_b64}',
'Content-Type':'application/x-www-form-urlencoded'
}
# send the post request to Authorisation server
response = requests.post(
clientCredentialEndpoint,
params=queryParams,
headers=headers,
)
print(response.status_code)
print(response.text)
whereas the curl command that I used (and worked) to send the request is:
curl -X POST -u '<client_id>:<client_secret>' \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'grant_type=client_credentials&scope=get_listings_data' \
'https://base_url/path/token'
Again, like I said, if I execute this curl command inside a Python script, it will successfully return the access token with no issue.
Does anyone know what I did wrong in my Python script which caused my request to always fail?
Thanks in advance!
My goodness me, I just realised that the -d in the curl command does not correspond to query params, it stands for 'data'.
Hence, I just need to change my Python script requests.post() a bit so that it looks like this:
response = requests.post(
clientCredentialEndpoint,
data=queryParams,
headers=headers,
)
Hope this helps others.
How do I construct a complete REST api request (using python) to retrieve the list of all pull requests for a repo based on some filters?
I'm using the url "https://bitbucket.org/api/2.0/repositories/YOUR_NAME/REPO_NAME/pullrequests"
I have the client key and secret from the oAuth settings.
I'm getting the access token using the following POST request.
$ curl -X POST -u "<key>:<secret>" https://bitbucket.org/site/oauth2/access_token -d grant_type=client_credentials
{"access_token": "{access_token}", "scopes": "pullrequest project team account", "expires_in": 7200, "refresh_token": "{refresh_token}", "token_type": "bearer"}
I'm getting a forbidden error.
Is something wrong with the API request?
You don't need to make a POST request to get the list of pull requests.
Just do a GET request with all the filters you want.
You should have read access granted for the user, using whose token you want to retrieve the list of pull requests. Generally 403-forbidden comes when you have no permissions. Once you have at least read access, you can go ahead a get the list using the way suggested by #rajatgoyal715. Also the authorization header value should be Bearer <token>. And add one more header Accept and set it to application/json. Hope this works.
Goodmorning,
i have some trouble in wrinting a callback method that it's used to login to my web app (hosted in gae)
#app.route('/callback')
def callback_handling():
env = os.environ
code = request.args.get('code')
json_header={'Content-Type': 'application/x-www-form-urlencoded'}
token_url = "https://{domain}/oauth/token".format(domain='mydomain')
token_payload = {
'client_id': 'myid',
'client_secret': 'mysecret',
'redirect_uri': 'http://localhost:8080/callback',
'code': code,
'grant_type': 'authorization_code'
}
encoded = urllib.urlencode(token_payload)
user_url = "https://{domain}/userinfo?access_token={access_token}"\
.format(access_token=token_info['access_token'])
user_info = urlfetch.Fetch(user_url, method=urlfetch.GET, headers=json_header)
session['profile'] = user_info
return redirect('/dashboard')
i costantly get error 401 unathorized..from debug console any ideas to fix?..reading over the internet i understand that i must use urlfetch from gae because is the only lib allowed in gae (requests does not in localhost)..
In your code, is this : "https://{domain}/userinfo" your own endpoint or is this some third-party that you are trying to auth with?
Either way the 401 unauthorised seems legit, and being thrown by the endpoint, If "https://{domain}/userinfo" is pointing to your own endpoint then being able to see that logic would help, alternatively if it is a third-party I would recommend testing your request with something like postman, to see what your request looks like, headers etc. and make sure that it matches what the endpoint is expecting.
Hope this helps.
I'm trying to use Google OAuth2 to get user's contact info. I'm not struggling with getting accesses, I am wondering that for some reason I've stopped getting refresh_token instead I get id_token (long JWT string).
I use python urllib to retrieve access information for users. My code is:
scope = 'https://accounts.google.com/o/oauth2/token'
params = urllib.urlencode({
'code': request.GET['code'],
'redirect_uri': settings.SOCIAL_AUTH_GOOGLE_REDIRECT_URI,
'client_id': settings.SOCIAL_AUTH_GOOGLE_OAUTH2_KEY,
'client_secret': settings.SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET,
'grant_type': 'authorization_code',
})
Response:
{u'access_token': u'hash',
u'token_type': u'Bearer',
u'expires_in': 3600,
u'id_token': u'really long hash'}
I use contacts scope https://www.google.com/m8/feeds/contacts/default/full?alt=json
When I'm trying to add to params access_type : offline I get the error below:
Failed to retrive access_token. Status: 400
Message: {
"error" : "invalid_request",
"error_description" : "Parameter not allowed for this message type: access_type"
}
So after that I am wondering:
Can I use id_token refresh my access_token ?
If first is True: How ?
Are there any differences between types of users who are getting authenticated, because I noticed that sometimes you get refresh_token, but I need to get it permanently, next time I make a OAuth2 flow I get id_token
I'm sure I'm far too late to help here, but I ran into the same issue so hopefully this will help others.
Google ONLY provides the refresh_token on the first authorization. If the account has already allowed access, the refresh_token will not be provided again. Try revoking access to the app from your google account, then re-authorizing. You will then receive the refresh_token.
If you need a refresh token, you better add access_type=offline and approval_prompt=force onto https://accounts.google.com/o/oauth2/auth?
var url = 'https://accounts.google.com/o/oauth2/auth?' +
'client_id=' + CLIENT_ID + '&' +
'response_type=code&access_type=offline&approval_prompt=force&' +
'redirect_uri=' + encodeURIComponent(REDIRECT_URL) +
'&scope=' + SCOPES;
Then the returned code will always give you a refresh code in the next handshake with https://www.googleapis.com/oauth2/v4/token