Skip to main content

Capture and store OAuth2 tokens for later use.

Project description

OAuth2 Token Capture for Django

This Django package that enables easy capture of OAuth2 tokens for the following providers:

  • X (Twitter)
  • LinkedIn
  • GitHub
  • Reddit
  • Pinterest
  • Facebook
  • Threads

Planned

  • Instagram
  • Youtube
  • TikTok

Features

  • OAuth2 token exchange
  • User information retrieval
  • Support for multiple providers
  • Easily extendable to support new providers
  • Manage multiple tokens for different users and providers

https://youtube.com/@leftsideresale?si=b7Be0pEbJGA57Y7J

Requirements

  • Python 3.6+
  • Django 3.0+
  • requests

You will also need to setup an OAuth2 application with each provider you want to use. This will give you a client ID and client secret that you will need to configure the package.


Installation

Install the package using pip:

pip install oauth2_capture

or while in development mode:

pip install -e .

or from another project, make sure to follow HEAD on master from https://github.com/heysamtexas/django-oauth2-capture:

pip install git+https://github.com/yourusername/django-oauth2-capture.git@master

Configuration

Add it to your installed apps in your Django settings file:

INSTALLED_APPS = [
    ...
    'oauth2_capture',
    ...
]

OAuth2 Configuration

You need to configure the OAuth2 providers in your Django settings file by adding the OAUTH2_CONFIG dictionary. Each provider requires specific configuration parameters:

OAUTH2_CONFIG = {
    "twitter": {
        "client_id": os.environ["TWITTER_CLIENT_ID"],
        "client_secret": os.environ["TWITTER_CLIENT_SECRET"],
        "scope": "tweet.read users.read tweet.write offline.access",
        "code_verifier": "challenge",  # Twitter-specific parameter
    },
    "linkedin": {
        "client_id": os.environ["LINKEDIN_CLIENT_ID"],
        "client_secret": os.environ["LINKEDIN_CLIENT_SECRET"],
        "scope": "profile email openid w_member_social",
    },
    "github": {
        "client_id": os.environ["GITHUB_CLIENT_ID"],
        "client_secret": os.environ["GITHUB_CLIENT_SECRET"],
        "scope": "user repo issues write:discussion",
    },
    "reddit": {
        "client_id": os.environ["REDDIT_CLIENT_ID"],
        "client_secret": os.environ["REDDIT_CLIENT_SECRET"],
        "scope": "identity edit read submit save",
    },
    "pinterest": {
        "client_id": os.environ["PINTEREST_CLIENT_ID"],
        "client_secret": os.environ["PINTEREST_CLIENT_SECRET"],
        "scope": "user_accounts:read boards:read_secret boards:read boards:write_secret boards:write pins:read pins:write pins:read_secret pins:write_secret",
    },
}

Usage

The package provides views and models to handle OAuth2 authentication and token storage. Here's a basic implementation:

  1. Include the OAuth2 URLs in your project's urls.py:
from django.urls import include, path

urlpatterns = [
    # ... your other URL patterns
    path('oauth2/', include('oauth2_capture.urls')),
]
  1. Create links to the OAuth2 authorization endpoints for your desired providers:
<a href="{% url 'oauth2_capture:authorize' 'github' %}">Connect with GitHub</a>
<a href="{% url 'oauth2_capture:authorize' 'twitter' %}">Connect with Twitter</a>
<a href="{% url 'oauth2_capture:authorize' 'linkedin' %}">Connect with LinkedIn</a>
<!-- Add more providers as needed -->
  1. Handle the callback and access the tokens in your views:
from oauth2_capture.models import OAuth2Token

def my_view(request):
    # Get a user's GitHub token
    token = OAuth2Token.objects.filter(
        user=request.user,
        provider='github'
    ).first()

    if token:
        # Use the token to make API requests
        access_token = token.access_token
        # ...

For more detailed examples, check out the demo app in the development/ directory of the repository, which shows complete implementation examples for all supported providers.


Adding a new provider

class NewProviderOAuth2Provider(OAuth2Provider):
    @property
    def authorize_url(self) -> str:
        return "https://newprovider.com/oauth/authorize"

    @property
    def token_url(self) -> str:
        return "https://newprovider.com/oauth/token"

    @property
    def user_info_url(self) -> str:
        return "https://api.newprovider.com/userinfo"

    def get_user_info(self, access_token: str) -> dict:
        headers = {"Authorization": f"Bearer {access_token}"}
        response = requests.get(self.user_info_url, headers=headers, timeout=10)
        return response.json()

    def exchange_code_for_token(self, code: str, redirect_uri: str) -> dict:
        data = {
            "grant_type": "authorization_code",
            "code": code,
            "redirect_uri": redirect_uri,
            "client_id": self.config["client_id"],
            "client_secret": self.config["client_secret"],
        }
        headers = {"Content-Type": "application/x-www-form-urlencoded"}
        response = requests.post(self.token_url, data=data, headers=headers, timeout=10)
        return response.json()

User Flow

The following is a simplified user flow for how we obtain and save the oauth tokens. The flow is as follows:

sequenceDiagram
    participant U as User
    participant C as Client
    participant P as Provider
    U->>C: Clicks on "connect" with provider
    C->>P: Redirects to provider's authorize URL
    P->>C: Redirects to client's redirect URI with code
    C->>P: Exchanges code for token
    P->>C: Returns token
    C->>P: Retrieves user info
    P->>C: Returns user info
    C->>U: Redirects to home page
    C->>C: Save or update the user token in database

Note: if the user is not logged in at their provider, they will be prompted to login before they can authorize the client. (This is not shown in the diagram)


Setting up your development environment

  1. Clone the repository
  2. Create a virtual environment
  3. Install the requirements
  4. Configure the environment variables
    1. Acquire the client ID and client secret from the providers
    2. Put client_id and secrets into local env file in the development/ folder
  5. Migrate the database with python manage.py migrate

Setup each provider by following the instructions in the docs/ folder.


License


Appendix

Provider's endpoints, docs, etc

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

oauth2_capture-0.4.0.tar.gz (109.8 kB view details)

Uploaded Source

Built Distribution

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

oauth2_capture-0.4.0-py3-none-any.whl (18.7 kB view details)

Uploaded Python 3

File details

Details for the file oauth2_capture-0.4.0.tar.gz.

File metadata

  • Download URL: oauth2_capture-0.4.0.tar.gz
  • Upload date:
  • Size: 109.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-requests/2.32.3

File hashes

Hashes for oauth2_capture-0.4.0.tar.gz
Algorithm Hash digest
SHA256 f043d1aa7e3d267f7d19bc4d33160d4311eda813ce0069380fa681aa78ad1835
MD5 67c50fc1aa229a63c53a562da2759ab2
BLAKE2b-256 ff6aed6842c7cb4f52136f676faee785748db01777fa18539fcc23c3d3a88a64

See more details on using hashes here.

File details

Details for the file oauth2_capture-0.4.0-py3-none-any.whl.

File metadata

File hashes

Hashes for oauth2_capture-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 05fe387db1458bc474c60a193359a27026fb89a5eae6ff074f7895746d97d70c
MD5 ed567e6633fba260e00f16ad22c63a62
BLAKE2b-256 8eddbc401c5225e3b460d30d02abe62fd1b8f9924dd78d8ae0a37e53dc3d0fbd

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