This documentation covers the common design of a Python OAuth 1.0 client. Authlib provides three implementations of OAuth 1.0 client:
requests_client.OAuth1Session
implementation of OAuth for Requests,
which is a replacement for requests-oauthlib.httpx_client.AsyncOAuth1Client
implementation of OAuth for HTTPX,
which is an async OAuth 1.0 client.requests_client.OAuth1Session
and httpx_client.AsyncOAuth1Client
shares the same API.
There are also frameworks integrations of Flask OAuth Client, Django OAuth Client and Starlette OAuth Client. If you are using these frameworks, you may have interests in their own documentation.
If you are not familiar with OAuth 1.0, it is better to read Introduce OAuth 1.0 now.
There are three steps in OAuth 1 to obtain an access token:
But first, we need to initialize an OAuth 1.0 client:
>>> client_id = 'Your Twitter client key'
>>> client_secret = 'Your Twitter client secret'
>>> # using requests client
>>> from authlib.integrations.requests_client import OAuth1Session
>>> client = OAuth1Session(client_id, client_secret)
>>> # using httpx client
>>> from authlib.integrations.httpx_client import AsyncOAuth1Client
>>> client = AsyncOAuth1Client(client_id, client_secret)
The first step is to fetch temporary credential, which will be used to generate authorization URL:
>>> request_token_url = 'https://api.twitter.com/oauth/request_token'
>>> request_token = client.fetch_request_token(request_token_url)
>>> print(request_token)
{'oauth_token': 'gA..H', 'oauth_token_secret': 'lp..X', 'oauth_callback_confirmed': 'true'}
Save this temporary credential for later use (if required).
You can assign a redirect_uri
before fetching the request token, if
you want to redirect back to another URL other than the one you registered:
>>> client.redirect_uri = 'https://your-domain.org/auth'
>>> client.fetch_request_token(request_token_url)
The second step is to generate the authorization URL:
>>> authenticate_url = 'https://api.twitter.com/oauth/authenticate'
>>> client.create_authorization_url(authenticate_url, request_token['oauth_token'])
'https://api.twitter.com/oauth/authenticate?oauth_token=gA..H'
Actually, the second parameter request_token
can be omitted, since session
is re-used:
>>> client.create_authorization_url(authenticate_url)
Now visit the authorization url that create_authorization_url generated, and grant the authorization.
When the authorization is granted, you will be redirected back to your registered callback URI. For instance:
https://example.com/twitter?oauth_token=gA..H&oauth_verifier=fcg..1Dq
If you assigned redirect_uri
in Fetch Access Token, the
authorize response would be something like:
https://your-domain.org/auth?oauth_token=gA..H&oauth_verifier=fcg..1Dq
Now fetch the access token with this response:
>>> resp_url = 'https://example.com/twitter?oauth_token=gA..H&oauth_verifier=fcg..1Dq'
>>> client.parse_authorization_response(resp_url)
>>> access_token_url = 'https://api.twitter.com/oauth/access_token'
>>> token = client.fetch_access_token(access_token_url)
>>> print(token)
{
'oauth_token': '12345-st..E',
'oauth_token_secret': 'o67..X',
'user_id': '12345',
'screen_name': 'lepture',
'x_auth_expires': '0'
}
>>> save_access_token(token)
Save this token to access protected resources.
The above flow is not always what we will use in a real project. When we are redirected to authorization endpoint, our session is over. In this case, when the authorization server send us back to our server, we need to create another session:
>>> # restore your saved request token, which is a dict
>>> request_token = restore_request_token()
>>> oauth_token = request_token['oauth_token']
>>> oauth_token_secret = request_token['oauth_token_secret']
>>> from authlib.integrations.requests_client import OAuth1Session
>>> # if using httpx: from authlib.integrations.httpx_client import AsyncOAuth1Client
>>> client = OAuth1Session(
... client_id, client_secret,
... token=oauth_token,
... token_secret=oauth_token_secret)
>>> # there is no need for `parse_authorization_response` if you can get `verifier`
>>> verifier = request.args.get('verifier')
>>> access_token_url = 'https://api.twitter.com/oauth/access_token'
>>> token = client.fetch_access_token(access_token_url, verifier)
Now you can access the protected resources. If you re-use the session, you don’t need to do anything:
>>> account_url = 'https://api.twitter.com/1.1/account/verify_credentials.json'
>>> resp = client.get(account_url)
<Response [200]>
>>> resp.json()
{...}
The above is not the real flow, just like what we did in Fetch Access Token, we need to create another session ourselves:
>>> access_token = restore_access_token_from_database()
>>> oauth_token = access_token['oauth_token']
>>> oauth_token_secret = access_token['oauth_token_secret']
>>> # if using httpx: from authlib.integrations.httpx_client import AsyncOAuth1Client
>>> client = OAuth1Session(
... client_id, client_secret,
... token=oauth_token,
... token_secret=oauth_token_secret)
>>> account_url = 'https://api.twitter.com/1.1/account/verify_credentials.json'
>>> resp = client.get(account_url)
Please note, there are duplicated steps in the documentation, read carefully and ignore the duplicated explains.
It is also possible to access protected resources with OAuth1Auth
object.
Create an instance of OAuth1Auth with an access token:
# if using requests
from authlib.integrations.requests_client import OAuth1Auth
# if using httpx
from authlib.integrations.httpx_client import OAuth1Auth
auth = OAuth1Auth(
client_id='..',
client_secret=client_secret='..',
token='oauth_token value',
token_secret='oauth_token_secret value',
...
)
If using requests
, pass this auth
to access protected resources:
import requests
url = 'https://api.twitter.com/1.1/account/verify_credentials.json'
resp = requests.get(url, auth=auth)
If using httpx
, pass this auth
to access protected resources:
import httpx
url = 'https://api.twitter.com/1.1/account/verify_credentials.json'
resp = await httpx.get(url, auth=auth)