Skip to main content

A utility for obtaining access tokens using the PKCE-enhanced authorization code flow (Oauth)

Project description

PKCE-flow

PKCE-flow is a utility for obtaining access tokens using the PKCE-enhanced authorization code flow (Oauth)

Quick Start

First Things First

We'll be walking through the creation of a utility for obtaining an access token that will allow us access GitLab resources on behalf of a particular user.

If you plan to work through this, then you'll need to take five minutes (approx.) to create an Application with GitLab, so that you can have a client id and secret.

You can use any other service of your choice which implements PKCE OAuth. The process will be the same.

Creating a PKCEFlowManager Instance

Subclass the Manager Class

from pkce_flow.managers import AbstractBasePKCEFlowManager


class GitLabPKCEFlowManager(AbstractBasePKCEFlowManager):
    pass

Configure the Required Attributes

from pkce_flow.managers import AbstractBasePKCEFlowManager


class GitLabPKCEFlowManager(AbstractBasePKCEFlowManager):
    client_id = 'our GitLab application id'
    client_secret = 'our GitLab application secret'
    redirect_uri = 'http://127.0.0.1:8000/oauth/gitlab/callback/'
    root_url = 'https://gitlab.com/oauth/'
    scope = 'read_api'

A quick description of the attributes we're defining:

  • client_id: The ID of the developer application that will be requesting access to the resources on the user's behalf. The application must have been already created by the developer with the service.

  • client_secret: The SECRET KEY of the developer application.

  • redirect_uri: The redirect uri or callback uri that was specified by the developer when they created the developer application.

  • root_url: The base url for authentication with the service.

  • scope: Space delimited permission scopes.

Override the Hook Methods

from pkce_flow.managers import AbstractBasePKCEFlowManager


class GitLabPKCEFlowManager(AbstractBasePKCEFlowManager):
    client_id = 'our GitLab application id'
    client_secret = 'our GitLab application secret'
    redirect_uri = 'http://127.0.0.1:8000/oauth/gitlab/callback/'
    root_url = 'https://gitlab.com/oauth/'
    scope = 'read_api'

    def store_user_secrets(self, user, state, code_verifier, code_challenge):
        # write code to persist the state, code verifier, and code challenge
        # against the user in a place you can retrieve them later
        ...

    def retrieve_user_state(self, user):
        # write code to retrieve the state which was persisted against
        # the argument user
        ...
        return state

    def retrieve_user_code_challenge(self, user):
        # write code to retrieve the code challenge which was
        # persisted against the argument user
        ...
        return code_challenge

    def retrieve_user_code_verifier(self, user):
        # write code to retrieve the code verifier which was
        # persisted against the argument user
        ...
        return code_verifier

    def check_user_state(self, user, state):
        # write code to check whether argument state is the same as
        # the state that was persisted against the argument user
        ...
        return is_same

Instantiate a Project-wide Manager from Your Subclass

gitlab_manager = GitLabPKCEFlowManager()

Using the Manager Instance

So, a user of your web app wants to give you permission to access resources on GitLab on their behalf. And you've created a GitLab PKCE-flow manager for this.

The next thing to do is to make the secrets needed for the PKCE flow.

state, verifier, challenge = gitlab_manager.make_user_secrets(user=user)

Since you've already taught your manager how to store secrets against a user, it will store these secrets against the argument user before returning them to you.

After this, you get the url which you will send/redirect the user to, so they can authorize your request for an access token on their behalf.

url = gitlab_manager.get_authorization_url(user=user)

Then in your web app, in the view which handles the endpoint corresponding to the redirect uri, you extract the state and code query parameters so you can fetch the user's access token with their values.

from requests.exceptions import RequestException
from pkce_flow.exceptions import StateForgeryException


state = ...  # extract value of the query param 'state' from request
code = ...  # extract value of the query param 'code' from request

try:
    token_resp = gitlab_manager.fetch_access_token(
        user=user, state=state, code=code
    )
except StateForgeryException:
    ...
except RequestException:
    ...
except Exception:
    ...

resp_data = token_resp.json()
access_token = resp_data['access_token']

And that is that!

Extended Discussion

TODO

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pkce_flow-0.1.1.tar.gz (5.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pkce_flow-0.1.1-py3-none-any.whl (6.7 kB view details)

Uploaded Python 3

File details

Details for the file pkce_flow-0.1.1.tar.gz.

File metadata

  • Download URL: pkce_flow-0.1.1.tar.gz
  • Upload date:
  • Size: 5.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.5 CPython/3.8.1 Windows/10

File hashes

Hashes for pkce_flow-0.1.1.tar.gz
Algorithm Hash digest
SHA256 059c56194cb5eab700ecb64ecd33e21f20bd403215de114fcc56bb9d683cee00
MD5 76eb4ac45a2f2d86cdc8f2e601dfb486
BLAKE2b-256 6a3e3cb2e50aa14cd420e7d87513adf6f7e4470114f2df7c1331bed0f8c63045

See more details on using hashes here.

File details

Details for the file pkce_flow-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: pkce_flow-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 6.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.5 CPython/3.8.1 Windows/10

File hashes

Hashes for pkce_flow-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 81e54e684fe20b74f066d09ccf00facbcb7ca8d0b9ac75b877c0f39c8e4f99dc
MD5 36ac72814cd5cb569530e5e46a726194
BLAKE2b-256 cc6dbce77af83572ea2a7677cbab5f5d66366e7ebc16e6fe4b1ad67598d9ef5a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page