Advanced Authentication

Keywords: magic links, oauth2 github google, login token, api tokens, bearer token, social authentication

Asok provides built-in tools for modern authentication methods like Magic Links and OAuth2 (Google, GitHub, etc.) without adding extra framework-specific packages.

2. OAuth2 (Social Login)

Asok includes a standard-library implementation for OAuth2 providers.

Supported Providers

  • Google

  • GitHub

Configuration

You will need to pass your Client ID and Client Secret from the provider dashboard.

Step 1: Redirect to Provider

from asok import Request

def get(request: Request):
    auth_url = request.auth.oauth.get_auth_url(
        provider_name="google",
        client_id="YOUR_CLIENT_ID",
        redirect_uri="https://myapp.com/auth/google/callback",
        state=request.session.get("oauth_state")
    )
    return request.redirect(auth_url)

Store the generated state value server-side and verify it in the callback before exchanging the authorization code.

Step 2: Handle Callback

from asok import Request

def get(request: Request):
    code = request.query.get("code")
    user_info = request.auth.oauth.callback(
        provider_name="google",
        client_id="YOUR_CLIENT_ID",
        client_secret="YOUR_CLIENT_SECRET",
        code=code,
        redirect_uri="https://myapp.com/auth/google/callback"
    )
    
    # user_info contains: email, name, picture, provider_id
    user = User.find(email=user_info["email"])
    if not user:
        user = User.create(email=user_info["email"], name=user_info["name"])
    
    request.login(user)
    return request.redirect("/")

3. API Tokens (Bearer Auth)

Asok supports stateless API authentication via Bearer tokens. This is ideal for mobile apps or external integrations.

Usage

Tokens are signed via the framework’s SECRET_KEY, making them stateless and naturally secure.

Generating a Token

from asok import Request

def get(request: Request):
    # Generate a permanent token for the current user
    token = request.auth.token.create(request, request.user.id)
    
    # Or generate a temporary token (e.g. 24 hours)
    token = request.auth.token.create(request, request.user.id, expires_in=86400)
    
    return request.api({"token": token})

Accessing your API

Clients should send the token in the Authorization header: Authorization: Bearer <your-token>

Asok’s request.user will automatically detect the token and authenticate the request.

# page/api/profile.py
from asok import Request

def get(request):
    if not request.user:
        return request.api_error("Unauthorized", status=401)
        
    return request.api({"email": request.user.email})

4. Roles & Permissions (RBAC)

Asok includes a granular Role-Based Access Control system. While primarily used by the Admin Interface, it is available for use in any part of your application.

Permission Format

Permissions are strings in the format slug.verb:

  • posts.view, posts.edit, users.delete

  • posts.* — all verbs for a specific model

  • * — superuser (all permissions)

Checking Permissions

If your User model has a roles relationship (auto-provided by the Admin module), you can check permissions easily:

if request.user.can("posts.edit"):
    # Allow action
    pass

5. Two-Factor Authentication (2FA)

Asok supports TOTP-based 2FA (compatible with Google Authenticator, Authy, etc.).

Enabling 2FA

The built-in Admin interface provides a complete flow for enabling and verifying 2FA. See the Admin 2FA documentation for details.

Manual Implementation

If you are building your own 2FA flow, you can use the underlying TOTP helpers (currently part of the asok.admin module).

Recommended flow:

  1. Generate a TOTP secret for the user and store it server-side.

  2. Display a QR code or provisioning URI once, during enrollment.

  3. Require a successful code entry before marking totp_enabled = True.

  4. Generate recovery codes and store only hashed versions.

  5. Rate-limit verification attempts to reduce brute-force risk.

6. Security Notes

  • SECRET_KEY: All tokens are signed using the SECRET_KEY configured in your .env. Never share this key.

  • Expiration: Magic Links expire in 1 hour by default.

  • HTTPS: OAuth2 requires HTTPS for redirect URIs in production.

  • State: Always generate and verify the OAuth state value to prevent CSRF.