I am developing an app that will read some tweets stats of my company. I want to let all the employees to connect with their twitter accounts.
I am facing the following problem: I am stuck at the "Exchange authorization code for access token".
The response url after Authorize is: https://example/v1/browser-callback?state=state&code=all0UTY5TVVMYmctNjZEQVpYYYYYYYYZZZZZXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
I suppose I have to change the code all0UTY5TVVMYmctNjZEQVpYYYYYYYYZZZZZXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX for access_token and access_token_secret, but I did not find how to do that on the documentation that twitter offers to us.
You need first to know the type of flow you are trying to implement
First you need to know what is the grant type of your client_id in the twitter side, i see in the callback there is code that means you are in normal authorization code or Authorization Code Flow with Proof Key for Code (PKCE), to know that check in your first call to twitter if you see in the params code_challenge and code_challenge_method if yes It's PKCE flow;
Second, I see that you have successfully done the first step of flow, then if you are in the PKCE, you need in your callback to send another request to get a final token like this:
client_id=your client_id&
code_verifier=the code generated by the application in the first step&
redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fcallback&
grant_type=authorization_code&
code=the code sent from twitter
I'm not sure what the docs looked like back in March, but to do this now you simply need to build the request headers with the code argument from the redirect URL. From the example url you gave (https://example/v1/browser-callback), your code is:
all0UTY5TVVMYmctNjZEQVpYYYYYYYYZZZZZXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
And the curl request you would make for a private client to retrieve the user's bearer and refresh token would be:
curl --location --request POST 'https://api.twitter.com/2/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic YOUR_BASE64_ENCODED_ClientID:ClientSecret_HERE'\
--data-urlencode 'code=all0UTY5TVVMYmctNjZEQVpYYYYYYYYZZZZZXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'redirect_uri=https://example/v1/browser-callback' \
--data-urlencode 'code_verifier=challenge'
where YOUR_BASE64_ENCODED_ClientID:ClientSecret_HERE is (per the docs):
To create the basic authorization header you will need to base64 encoding on your Client ID and Client Secret which can be obtained from your App’s “Keys and Tokens” page inside of the developer portal.
You'll need to make this request to get the initial bearer token/refresh token for private clients within 30 seconds of receiving the code at your callback URL after the user has authorized your app.
Related
i have problem for running postman POST using python code.
first i generate python code from fiddler, i capture when i running postman POST from website.
Capture with fiddler
and then the problem is here, the bearer token only work 5-15minutes, after that i got response 401, because bearer token is expired.
Python Code for running my postman
so i want to change the Bearer token to basic auth ( use my user and password of my postman acc)
i already try change Authorization value to apikey and base64encode(user:pass) still not working.
please who experince in this , help my case, thanks.
thanks for reading - my questions are simple:
What am I doing wrong?
What am I missing?
Do I need to additional access to make use of the report engine?
I cannot seem to obtain balance or transaction data from my pp account using a simple python client despite what appears to be correct use of documented APIs.
I have:
a business account
dev portal access
valid creds for a Sandbox and Live API use
My py client wraps a few API calls and successfully completes the following:
obtain API token using dev portal creds
use API token to make valid HTTP requests to the balances and transactions API resources
API responses indicate 200 OK
However, except for the OAuth token request, all of the responses all say Empty XML data
Pseudo-sample code
# -- pp_auth_header is a global, contains Auth Bearer token
def get_balances():
print("get_balances...")
headers = pp_auth_header
endpoint = "/v1/reporting/balances"
query = "?currency_code=USD&as_of_time=2021-02-22T00:00:00-0700"
r = requests.get(pp_report_eng_url + endpoint + query, headers=pp_auth_header)
print("get_balances - status: {}".format(r.status_code))
if r.status_code == 200:
print("get_balances - r.text: {}".format(r.text))
# -- output of the above is
get_balances...
get_balances - url: https://api-m.sandbox.paypal.com/v1/reporting/balances?currency_code=USD&as_of_time=2021-02-22T00:00:00-0700
get_balances - status: 200
get_balances - r.text: Empty XML data
Generate an acess_token and then test from the command line with curl, as documented:
curl -v -X GET
https://api-m.sandbox.paypal.com/v1/reporting/balances?currency_code=USD&as_of_time=2016-10-15T06:07:00-0700
\
-H "Content-Type: application/json" \
-H "Authorization: Bearer Access-Token"
Ensure you pass the headers described there, including "Content-Type: application/json".
PayPal REST APIs do not return XML.
If this doesn't work, post the output of that curl -v command as well as the scopes returned by the oauth2 token request. Update your question with those details.
Trying to get Twitter to authenticate my get request to the new api for recent tweets around a particular topic. I have some issues with the authentication, that I can't seem to pin down. I authenticated my application using a client key and client secret, then authenticated a user and accepted that the app can read and write permissions. With the users authentication token and secret I tried to authenticate to get the data from the newish api and got bad authentication error.
Can you see what I am doing wrong?:
curl --request GET --url 'https://api.twitter.com/2/tweets/search/recent?query=python' --header \
'authorization: OAuth \
oauth_consumer_key="i_put_api_key_here",\
oauth_consumer_secret="i_put_api_secret_here",\
oauth_token="i_put_user_token_after_accepting_app_can_make_changes",\
oauth_token_secret="i_put_oauth_token_secret", \
oauth_signature_method="HMAC-SHA1",\
oauth_timestamp="",\
oauth_version="1.0"'
return data is:
{"title":"Unauthorized","type":"about:blank","status":401,"detail":"Unauthorized"}
I'm referring to this document: https://developer.twitter.com/en/docs/authentication/oauth-1-0a
I'm pretty sure I am supplying all the data it needs correctly.
Python saved the day. You can request a bearer token from the Twitter Api dashboard for the app. Then use OAuth 2.0 like so,
def get_data(url):
headers = {'Authorization': "Bearer " + str(TWITTER_BEARER_TOKEN) }
response = requests.get(url, headers=headers)
response_data = response.json()
return response_data
get_data('https://api.twitter.com/2/tweets/search/recent?query="Python";max_results=10')
Out[20]:
{'data': [{'id': '1294146621652045826',
'text': 'RT #jacoblawherlin: #Taco_Farmer1 Maybe this is why Python is so popular for data science but not software dev (in addition to performance)…'},
I want to route my Google Analytics Reporting API request (code will be in AWS Lambda) through a gateway which accepts a REST endpoint only. Since I cant use the Client package method in my interaction with the gateway, I need to query the API as a REST-ful endpoint.
The official document says this (Link) :
Authorization: Bearer {oauth2-token}
GET https://www.googleapis.com/analytics/v3/data/ga
?ids=ga:12345
&start-date=2008-10-01
&end-date=2008-10-31
&metrics=ga:sessions,ga:bounces
I do not know to create the oauth2-token in Python. I have created a service account and have the secrets_json which includes the client id and secret key.
Then client package method as given in this link works. But I need the Rest method only!
Using these, how can I create the oauth2-token ?
You can use Oauth2 for this I have done it in the past but you will need to monitor it. You will need to authorize this code once and save the refresh token. Refresh tokens are long lived they normally dont expire but your code should be able to contact you if it does so that you can authorize it again. If you save the refresh token you can use the last step at any time to request a new access token.
Oauth2 is basicly built up into three calls. I can give you the HTTP calls i will let you work out the Python Google 3 Legged OAuth2 Flow
Authencation and authorization
The first thing you need is the permission of the user. To get that you build a link on the authorization server. This is a HTTP get request you can place it in a normal browser window to test it.
GET https://accounts.google.com/o/oauth2/auth?client_id={clientid}&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://www.googleapis.com/auth/analytics.readonly&response_type=code
Note on redirect uri. If you are running this on a server or something then use urn:ietf:wg:oauth:2.0:oob it basicly tells the server to return the code back where it came from other wise if you are hosing on a website you can supply a url to the page that will be handling the response.
If the user accepts the above then you will have an authorization code.
Exchange code
What you need to do next is exchange the authorization code returned by the above response and request an access token and a refresh token. THis is a http post call
POST https://accounts.google.com/o/oauth2/token
code=4/X9lG6uWd8-MMJPElWggHZRzyFKtp.QubAT_P-GEwePvB8fYmgkJzntDnaiAI&client_id={ClientId}&client_secret={ClientSecret}&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code
The body parameter should be as i have shown separated by & and the content type of the request is application/x-www-form-urlencoded
Responce
{
"access_token" : "ya29.1.AADtN_VSBMC2Ga2lhxsTKjVQ_ROco8VbD6h01aj4PcKHLm6qvHbNtn-_BIzXMw",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "1/J-3zPA8XR1o_cXebV9sDKn_f5MTqaFhKFxH-3PUPiJ4"
}
The access token can be used in all of your requests to the api by adding either an authorization header bearer token with the access token or by sending access_token= as your parameter in your requests.
Refresh access token
Refresh tokens are long lived they should not expire they can so you code should be able to handle that but normally they are good forever. Access tokens are only valid for one hour and you will need to request a new access token.
POST https://accounts.google.com/o/oauth2/token
client_id={ClientId}&client_secret={ClientSecret}&refresh_token=1/ffYmfI0sjR54Ft9oupubLzrJhD1hZS5tWQcyAvNECCA&grant_type=refresh_token
response
{
"access_token" : "ya29.1.AADtN_XK16As2ZHlScqOxGtntIlevNcasMSPwGiE3pe5ANZfrmJTcsI3ZtAjv4sDrPDRnQ",
"token_type" : "Bearer",
"expires_in" : 3600
}
I am using JWT token authentication with Django REST
$ curl -X POST -d "username=admin&password=abc123" http://localhost:8000/api-token-auth/
and then
$ curl -H "Authorization: JWT <your_token>" http://localhost:8000/protected-url/
My points is if someone has to enter username / password in curl to get token and then use that token to get url in 2 steps. Then why not use username / password with basic authentication . as that will be with one request only.
What advantage will token give us . we have to type username / password anyway in token AUTH as well
You are right, if that would be the normal workflow there would be not much advantage. Expect that token auth has slightly better performance, because you don't have to hash the password.
But normally the token is stored on the client side. Imagine a mobile app. There you login once to obtain and store the token. Now you can do authenticated API requests without username/password.