35

For a project someone gave me this data that I have used in Postman for testing purposes:

In Postman this works perfectly.

Auth URL: https://api.example.com/oauth/access_token
Access Token URL: https://api.example.com/access_token
client ID: abcde
client secret: 12345
Token name: access_token
Grant type: Client Credentials

All I need is to get back the access token.

Once, I got the access token I can continue.

I have already tried several Python packages and some custom code, but somehow this seemingly simple task starts to create a real headache.

One exemple I tried:

import httplib
import base64
import urllib
import json

def getAuthToken():
    CLIENT_ID = "abcde"
    CLIENT_SECRET = "12345"
    TOKEN_URL = "https://api.example.com/oauth/access_token"

    conn = httplib.HTTPSConnection("api.example.com")

    url = "/oauth/access_token"

    params = {
        "grant_type": "client_credentials"
    }

    client = CLIENT_ID
    client_secret = CLIENT_SECRET

    authString = base64.encodestring('%s:%s' % (client, client_secret)).replace('\n', '')

    requestUrl = url + "?" + urllib.urlencode(params)

    headersMap = {
        "Content-Type": "application/x-www-form-urlencoded",
        "Authorization": "Basic " + authString
    }

    conn.request("POST", requestUrl, headers=headersMap)

    response = conn.getresponse()

    if response.status == 200:
        data = response.read()
        result = json.loads(data)

        return result["access_token"]

Then I have got this one:

import requests
import requests.auth

CLIENT_ID = "abcde"
CLIENT_SECRET = "12345"
TOKEN_URL = "https://api.example.com/oauth/access_token"
REDIRECT_URI = "https://www.getpostman.com/oauth2/callback"

def get_token(code):
    client_auth = requests.auth.HTTPBasicAuth(CLIENT_ID, CLIENT_SECRET)
    post_data = {"grant_type": "client_credentials",
                 "code": code,
                 "redirect_uri": REDIRECT_URI}
    response = requests.post(TOKEN_URL,
                             auth=client_auth,
                             data=post_data)
    token_json = response.json()
    return token_json["access_token"]

If this would work, what should I put into the code parameter

I really hope someone can help me out here.

Thanks in advance.

5 Answers 5

41

Before using it, you need to pip install requests

import requests


def get_access_token(url, client_id, client_secret):
    response = requests.post(
        url,
        data={"grant_type": "client_credentials"},
        auth=(client_id, client_secret),
    )
    return response.json()["access_token"]


get_access_token("https://api.example.com/access_token", "abcde", "12345")

The client_id identifies the client, the client_secret authenticates the client. You get the access_token for follow-up requests.

There are some alternative names:

  • client_id: "consumer key" in Salesforce
  • client_secret: "consumer secret" in Salesforce
  • access_token: oauth-token
Sign up to request clarification or add additional context in comments.

8 Comments

Where did you get the url from?
From the API documentation against which I want to authenticate. For bad documentations, educated guesses are necessary
This should be the highest voted answer, works great without having to include rauth
This snippet works for Salesforce client credentials "connected app". Salesforce calls it "Consumer key" and "Consumer secret" in their setup.
Thanks - I've added it to the answer
|
15

I was finally able to get it done by using the rauth library (pip install rauth).

This is the code I used:

from rauth import OAuth2Service

class ExampleOAuth2Client:
    def __init__(self, client_id, client_secret):
        self.access_token = None

        self.service = OAuth2Service(
            name="foo",
            client_id=client_id,
            client_secret=client_secret,
            access_token_url="http://api.example.com/oauth/access_token",
            authorize_url="http://api.example.com/oauth/access_token",
            base_url="http://api.example.com/",
        )

        self.get_access_token()

    def get_access_token(self):
        data = {'code': 'bar',  # specific to my app
                'grant_type': 'client_credentials', # generally required! 
               }

        session = self.service.get_auth_session(data=data, decoder=json.loads)

        self.access_token = session.access_token

5 Comments

Can you please explain your code a little bit? I can't seem to get it to work. Thanks in advance!
can someone explain what is the 'bar' under 'code'? Some random string? some kind of url?
Is this using the rauth library?
Could you please explain your code/provide a complete answer? What library have you used? What is "bar"?
'code': 'bar' is specific to the application. Your application will probably not require this, or may use other parameters. If no parameters are required, you can safely leave it away
2

Simply (in case of Facebook Authentication):

import requests, json

access_token = requests.get("https://graph.facebook.com/oauth/access_token?grant_type=client_credentials&client_id=your_client_id&client_secret=your_client_secret").json()["access_token"]

Or you can use rauth library.

In the docs there is an interesting example with facebook oAuth2 authentication:

from rauth import OAuth2Service

facebook = OAuth2Service(
client_id='your_client_id',
client_secret='your_client_secret',
name='facebook',
authorize_url='https://graph.facebook.com/oauth/authorize',
access_token_url='https://graph.facebook.com/oauth/access_token',
base_url='https://graph.facebook.com/')

and after open a session:

session = facebook.get_auth_session(data={'code': 'foo','redirect_uri': redirect_uri})

in the session json there is your access token

2 Comments

last commit for rauth library is in 2015, is this library still maintained?
I would say no. Try 'oauthlib' which seems popular enough and had a commit 9 days ago (07-Aug-2020)
2

You can use the below code when you don't have the client_secret.

Import these two libraries - import requests & import json

auth_server_url = "**mention_your_url**"

data = {"client_id": "**mention_your_client_id**", "grant_type": "**your_grant_type**", "username":"**your_username**", "password":"**your_password**", "scope": "**your_scope**"}

response = requests.post(auth_server_url, data=data, verify=False, allow_redirects=False)
tokens = json.loads(response.text)
print(tokens['access_token'])

Comments

0

I found this to work:

from oauthlib.oauth2 import BackendApplicationClient
from requests.auth import HTTPBasicAuth
from requests_oauthlib import OAuth2Session

# Set the OAuth2 provider URL and client credentials
provider_url = "https://oauth2.provider.com"
client_id = "your-client-id"
client_secret = "your-client-secret"

# Create a BackendApplicationClient object
client = BackendApplicationClient(client_id=client_id)

# Create an OAuth2Session object
oauth = OAuth2Session(client=client)

# Get the access token
token = oauth.fetch_token(
    token_url=provider_url + "/oauth2/token",
    auth=HTTPBasicAuth(client_id, client_secret)
)

# Print the access token
print(token["access_token"])

This code will create an OAuth2Session object using the oauthlib library and use it to get an access token from the OAuth2 provider. The provider URL, client ID, and client secret must be set to the correct values for your application. Once you have the access token, you can use it to authenticate API calls to the OAuth2 provider.

This is just an example and may not work with all OAuth2 providers. You may need to adjust the code and the parameters to match the specific requirements of your OAuth2 provider.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.