CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-django-oauth-toolkit

OAuth2 Provider for Django web applications with complete server functionality, token management, and authorization endpoints.

Pending
Overview
Eval results
Files

oauth2-endpoints.mddocs/

OAuth2 Endpoints

Django OAuth Toolkit provides complete OAuth2 server endpoints implementing RFC 6749 and related specifications. These views handle authorization, token issuance, revocation, and introspection with support for all standard OAuth2 flows.

Capabilities

Authorization Endpoint

OAuth2 authorization endpoint that handles authorization requests and user consent.

class AuthorizationView(BaseAuthorizationView):
    """
    OAuth2 authorization endpoint (/o/authorize/).
    
    Handles authorization requests for all grant types:
    - Authorization Code Grant
    - Implicit Grant  
    - OpenID Connect Hybrid Flow
    
    Methods:
        GET: Display authorization form to user
        POST: Process user authorization decision
        
    Query Parameters:
        response_type: 'code', 'token', or 'id_token' combinations
        client_id: OAuth2 client identifier
        redirect_uri: Where to redirect after authorization
        scope: Requested OAuth2 scopes
        state: Client state parameter
        nonce: OIDC nonce for ID token
        code_challenge: PKCE code challenge
        code_challenge_method: PKCE challenge method ('plain' or 'S256')
        claims: OIDC claims parameter
        
    Returns:
        Authorization form or redirect to client with code/token
    """
    
    template_name = "oauth2_provider/authorize.html"
    form_class = AllowForm
    
    def get(self, request, *args, **kwargs):
        """Display authorization form"""
    
    def post(self, request, *args, **kwargs):
        """Process authorization decision"""

Token Endpoint

OAuth2 token endpoint for issuing and refreshing access tokens.

class TokenView(BaseTokenView):
    """
    OAuth2 token endpoint (/o/token/).
    
    Handles token requests for all grant types:
    - Authorization Code Grant
    - Resource Owner Password Credentials Grant
    - Client Credentials Grant
    - Refresh Token Grant
    
    Methods:
        POST: Issue or refresh access tokens
        
    Form Parameters:
        grant_type: Type of grant being used
        code: Authorization code (authorization_code grant)
        redirect_uri: Redirect URI used in authorization
        username: Resource owner username (password grant)
        password: Resource owner password (password grant)
        refresh_token: Refresh token (refresh_token grant)
        scope: Requested scopes
        client_id: OAuth2 client identifier
        client_secret: OAuth2 client secret
        code_verifier: PKCE code verifier
        
    Returns:
        JSON response with access_token, token_type, expires_in, refresh_token, scope
    """
    
    def post(self, request, *args, **kwargs):
        """Process token request and return JSON response"""

Token Revocation Endpoint

OAuth2 token revocation endpoint implementing RFC 7009.

class RevokeTokenView(BaseRevokeTokenView):
    """
    OAuth2 token revocation endpoint (/o/revoke_token/).
    
    Revokes access tokens and refresh tokens as per RFC 7009.
    
    Methods:
        POST: Revoke specified token
        
    Form Parameters:
        token: The token to revoke (access or refresh token)
        token_type_hint: Hint about token type ('access_token' or 'refresh_token')
        client_id: OAuth2 client identifier
        client_secret: OAuth2 client secret (for confidential clients)
        
    Returns:
        HTTP 200 on successful revocation
        HTTP 400 for invalid requests
    """
    
    def post(self, request, *args, **kwargs):
        """Revoke the specified token"""

Token Introspection Endpoint

OAuth2 token introspection endpoint implementing RFC 7662.

class IntrospectTokenView(BaseIntrospectTokenView):
    """
    OAuth2 token introspection endpoint (/o/introspect/).
    
    Provides metadata about OAuth2 tokens as per RFC 7662.
    
    Methods:
        POST: Return token metadata
        
    Form Parameters:
        token: The token to introspect
        token_type_hint: Hint about token type
        client_id: OAuth2 client identifier  
        client_secret: OAuth2 client secret
        
    Returns:
        JSON response with token metadata:
        - active: Boolean indicating if token is active
        - scope: Space-separated list of scopes
        - client_id: Client identifier
        - username: Resource owner username
        - token_type: Type of token
        - exp: Expiration timestamp
        - iat: Issued at timestamp
        - sub: Subject identifier
        - aud: Audience
        - iss: Issuer
    """
    
    def post(self, request, *args, **kwargs):
        """Return token introspection data"""

URL Patterns

Base OAuth2 URLs

Core OAuth2 endpoint URL patterns that should be included in your Django URL configuration.

base_urlpatterns = [
    path("authorize/", views.AuthorizationView.as_view(), name="authorize"),
    path("token/", views.TokenView.as_view(), name="token"),
    path("revoke_token/", views.RevokeTokenView.as_view(), name="revoke-token"),
    path("introspect/", views.IntrospectTokenView.as_view(), name="introspect"),
]

Usage Examples

URL Configuration

# urls.py
from django.urls import path, include

urlpatterns = [
    # Include OAuth2 URLs
    path('o/', include('oauth2_provider.urls', namespace='oauth2_provider')),
    # Your app URLs
    path('api/', include('myapp.urls')),
]

Authorization Code Flow

# Client initiates authorization request
# GET /o/authorize/?response_type=code&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=read+write&state=STATE

# After user authorization, client receives:
# HTTP/1.1 302 Found
# Location: REDIRECT_URI?code=AUTHORIZATION_CODE&state=STATE

# Client exchanges code for token
# POST /o/token/
# Content-Type: application/x-www-form-urlencoded
# 
# grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=REDIRECT_URI&client_id=CLIENT_ID&client_secret=CLIENT_SECRET

# Response:
# {
#   "access_token": "ACCESS_TOKEN",
#   "token_type": "Bearer",
#   "expires_in": 3600,
#   "refresh_token": "REFRESH_TOKEN",
#   "scope": "read write"
# }

Client Credentials Flow

# Server-to-server authentication
# POST /o/token/
# Content-Type: application/x-www-form-urlencoded
# Authorization: Basic BASE64(CLIENT_ID:CLIENT_SECRET)
#
# grant_type=client_credentials&scope=api

# Response:
# {
#   "access_token": "ACCESS_TOKEN",
#   "token_type": "Bearer", 
#   "expires_in": 3600,
#   "scope": "api"
# }

Resource Owner Password Credentials Flow

# Direct username/password authentication (use carefully)
# POST /o/token/
# Content-Type: application/x-www-form-urlencoded
#
# grant_type=password&username=USERNAME&password=PASSWORD&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&scope=read+write

# Response:
# {
#   "access_token": "ACCESS_TOKEN",
#   "token_type": "Bearer",
#   "expires_in": 3600,
#   "refresh_token": "REFRESH_TOKEN", 
#   "scope": "read write"
# }

Refresh Token Flow

# Refresh expired access token
# POST /o/token/
# Content-Type: application/x-www-form-urlencoded
#
# grant_type=refresh_token&refresh_token=REFRESH_TOKEN&client_id=CLIENT_ID&client_secret=CLIENT_SECRET

# Response:
# {
#   "access_token": "NEW_ACCESS_TOKEN",
#   "token_type": "Bearer",
#   "expires_in": 3600,
#   "refresh_token": "NEW_REFRESH_TOKEN",
#   "scope": "read write"
# }

Token Revocation

# Revoke access token
# POST /o/revoke_token/
# Content-Type: application/x-www-form-urlencoded
# Authorization: Basic BASE64(CLIENT_ID:CLIENT_SECRET)
#
# token=ACCESS_TOKEN&token_type_hint=access_token

# Response: HTTP 200 OK (empty body)

# Revoke refresh token (also revokes associated access tokens)
# POST /o/revoke_token/
# Content-Type: application/x-www-form-urlencoded
#
# token=REFRESH_TOKEN&token_type_hint=refresh_token&client_id=CLIENT_ID&client_secret=CLIENT_SECRET

Token Introspection

# Introspect token for metadata
# POST /o/introspect/
# Content-Type: application/x-www-form-urlencoded
# Authorization: Basic BASE64(CLIENT_ID:CLIENT_SECRET)
#
# token=ACCESS_TOKEN

# Active token response:
# {
#   "active": true,
#   "scope": "read write",
#   "client_id": "client123",
#   "username": "user@example.com",
#   "token_type": "Bearer",
#   "exp": 1640995200,
#   "iat": 1640991600,
#   "sub": "user@example.com",
#   "aud": "client123"
# }

# Inactive token response:
# {
#   "active": false
# }

PKCE (Proof Key for Code Exchange)

# Authorization request with PKCE
# GET /o/authorize/?response_type=code&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=read&code_challenge=CODE_CHALLENGE&code_challenge_method=S256

# Token exchange with code verifier
# POST /o/token/
# Content-Type: application/x-www-form-urlencoded
#
# grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=REDIRECT_URI&client_id=CLIENT_ID&code_verifier=CODE_VERIFIER

Custom Views

from oauth2_provider.views.base import BaseAuthorizationView
from django.shortcuts import render

class CustomAuthorizationView(BaseAuthorizationView):
    """Custom authorization view with custom template"""
    
    template_name = "myapp/custom_authorize.html"
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # Add custom context
        context['custom_data'] = 'Custom authorization page'
        return context

# Use in URL configuration
# path('custom/authorize/', CustomAuthorizationView.as_view(), name='custom_authorize')

Error Handling

OAuth2 endpoints return standard error responses following RFC 6749:

# Authorization endpoint errors (redirect to client):
# error=invalid_request&error_description=Missing+client_id+parameter
# error=unauthorized_client&error_description=Client+not+authorized
# error=access_denied&error_description=User+denied+authorization
# error=unsupported_response_type&error_description=Response+type+not+supported
# error=invalid_scope&error_description=Requested+scope+invalid
# error=server_error&error_description=Server+encountered+error

# Token endpoint errors (JSON response):
# {
#   "error": "invalid_request",
#   "error_description": "Missing grant_type parameter"
# }
# 
# {
#   "error": "invalid_client", 
#   "error_description": "Client authentication failed"
# }
#
# {
#   "error": "invalid_grant",
#   "error_description": "Authorization code has expired"
# }
#
# {
#   "error": "unsupported_grant_type",
#   "error_description": "Grant type not supported"
# }

Install with Tessl CLI

npx tessl i tessl/pypi-django-oauth-toolkit

docs

drf-integration.md

index.md

management-commands.md

management-views.md

models.md

oauth2-endpoints.md

oidc.md

settings.md

view-protection.md

tile.json