How to implement OAuth authentication in a Python application using the BoldSign API?

OAuth2 is a protocol that lets applications securely access the BoldSign API. It uses the OpenID Connect framework for strong and standardized authentication.

To get an access token and use the API, you can use BoldSign's supported OAuth2 workflows, like Client Credential or Authorization Code Grant. This guide focuses on the Authorization Code Grant flow, offering a detailed walkthrough with code examples to help you integrate OAuth2 authentication into your python application easily.

Below is a detailed walkthrough with code examples for each part of the process.

Create an OAuth2 Application in BoldSign

To start the OAuth2 authorization process, you need to create an OAuth2 application in BoldSign. This application will provide you with the necessary credentials client ID and client secret to authenticate and interact with the BoldSign API.

To create an OAuth app, refer to the article Create an OAuth app

Implement Authorization Code Flow

To begin the OAuth2 authorization code flow with Python, you need to set up a web server that handles the redirect URI endpoint. This endpoint is crucial for receiving the authorization code and exchanging it for access and refresh tokens. Ensure you have the necessary packages installed. You will need requests and Flask for HTTP requests and setting up the web server.

Here's a step-by-step guide to Set Up the Authorization Endpoint.

Code snippet

from flask import Flask, redirect, request, jsonify
import requests

app = Flask(__name__)

CLIENT_ID = 'YOUR_CLIENT_ID'
CLIENT_SECRET = 'YOUR_CLIENT_SECRET'
REDIRECT_URI = 'http://localhost:5000/callback'
AUTHORIZATION_URL = 'https://account.boldsign.com/connect/authorize'
TOKEN_URL = 'https://account.boldsign.com/connect/token'
SCOPE = 'openid profile email offline_access BoldSign.Documents.All'
CODE_VERIFIER = 'YOUR_CODE_VERIFIER'
CODE_CHALLENGE = 'YOUR_CODE_CHALLENGE'

@app.route('/authorize')
def authorize():
    authorization_uri = (f'{AUTHORIZATION_URL}?response_type=code&client_id={CLIENT_ID}'
                         f'&redirect_uri={REDIRECT_URI}&scope={SCOPE}&code_challenge={CODE_CHALLENGE}'
                         f'&code_challenge_method=S256')
    return redirect(authorization_uri)

@app.route('/callback')
def callback():
    auth_code = request.args.get('code')
    token_data = {
        'grant_type': 'authorization_code',
        'client_id': CLIENT_ID,
        'client_secret': CLIENT_SECRET,
        'code': auth_code,
        'redirect_uri': REDIRECT_URI,
        'code_verifier': CODE_VERIFIER
    }
    response = requests.post(TOKEN_URL, data=token_data)
    if response.status_code != 200:
        return f"Error: {response.json()}", 400
    tokens = response.json()
    return jsonify(tokens)

if __name__ == '__main__':
    app.run(port=5000)


In the provided code example, replace CLIENT ID with your client id from BoldSign application, CLIENT SECRET with your client secret from BoldSign application.

Generate PKCE Code Verifier and Challenge

When implementing OAuth2 with PKCE (Proof Key for Code Exchange), you need to generate a code verifier and a code challenge to enhance the security of your authorization flow. The code verifier is a random string, and the code challenge is a hashed version of the verifier, both of which are used to verify the authenticity of the authorization request.

To generate a PKCE code verifier and challenge in python, you can use the following utility function:

Code snippet

import base64
import hashlib
import os

def base64_url_encode(input: bytes) -> str:
    return base64.urlsafe_b64encode(input).rstrip(b'=').decode('utf-8')

def generate_pkce_codes() -> (str, str):
    code_verifier = base64_url_encode(os.urandom(32))
    code_challenge = base64_url_encode(hashlib.sha256(code_verifier.encode('utf-8')).digest())
    return code_verifier, code_challenge

# Example usage
code_verifier, code_challenge = generate_pkce_codes()
print(f'Code Verifier: {code_verifier}')
print(f'Code Challenge: {code_challenge}')

Refresh Access Token

Once you have the refresh token, you can use it to obtain a new access token without requiring the user to reauthorize your application. This process ensures continuous access to the BoldSign API. Here's how you can do it:

Code snippet

import requests

CLIENT_ID = 'YOUR_CLIENT_ID'
CLIENT_SECRET = 'YOUR_CLIENT_SECRET'
TOKEN_URL = 'https://account.boldsign.com/connect/token'

def refresh_access_token(refresh_token):
    token_data = {
        'grant_type': 'refresh_token',
        'client_id': CLIENT_ID,
        'client_secret': CLIENT_SECRET,
        'refresh_token': refresh_token
    }
    response = requests.post(TOKEN_URL, data=token_data)
    if response.status_code != 200:
        print(f"Error refreshing access token: {response.json()}")
        return None
    tokens = response.json()
    print(f'New access token: {tokens["access_token"]}')
    print(f'New refresh token: {tokens["refresh_token"]}')
    return tokens

# Example usage
refresh_access_token('YOUR_CURRENT_REFRESH_TOKEN')

Testing the Token Refresh Endpoint

You can test the /refresh-token endpoint using Postman or an HTML form. Here’s how to do it with Postman:

  1. Create a new POST request.
  2. Set the URL to {Your application URL}/refresh-token.
  3. Set the Body to x-www-form-urlencoded and add the key-value pairs: refresh_token: The refresh token you received from the initial token exchange.
  4. Send the request and verify that you receive a new access token and refresh token in the response.

Using these techniques, you can securely integrate OAuth2 authentication into your Python applications and access the BoldSign API.