Skip to main content

Flaxon OAuth Google

Flaxon Logo

PyPI version License: MIT Code style: ruff

Google OAuth 2.0 authentication plugin for Flaxon framework.

Table of Contents

Features

  • 🔐 OAuth 2.0 Authorization Code Flow — Full OAuth 2.0 implementation
  • 👤 User Info Retrieval — Fetch user profile from Google's API
  • 🔄 Session Management — Optional session creation after authentication
  • 🛡️ CSRF Protection — State parameter validation
  • ⚙️ Configurable Scopes — Request only the permissions you need
  • 🧩 User Mapping — Map Google user data to your app's user model
  • 🎯 Error Handling — Graceful OAuth error handling
  • 🔁 Refresh Tokens — Automatic token refresh support

Installation

pip install flaxon-oauth-google

Quick Start

from flaxon import Flaxon
from flaxon_oauth_google import GoogleOAuthPlugin

app = Flaxon("my-app")

# Basic usage with environment variables
app.plugins.load_plugin(GoogleOAuthPlugin(
    client_id="your-client-id.apps.googleusercontent.com",
    client_secret="your-client-secret",
    redirect_uri="https://yourapp.com/auth/google/callback",
))

@app.get("/")
async def home(request):
    return """
    <a href="/auth/google/login">Sign in with Google</a>
    """

Configuration

Environment Variables

# Required
export GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
export GOOGLE_CLIENT_SECRET=your-client-secret

# Optional
export GOOGLE_REDIRECT_URI=https://yourapp.com/auth/google/callback
export GOOGLE_SCOPES=openid,email,profile
export GOOGLE_SUCCESS_REDIRECT=/dashboard
export GOOGLE_FAILURE_REDIRECT=/login?error=oauth_failed

With Flaxon Config

app = Flaxon("my-app", config={
    "GOOGLE_CLIENT_ID": "your-client-id",
    "GOOGLE_CLIENT_SECRET": "your-client-secret",
    "GOOGLE_REDIRECT_URI": "https://yourapp.com/auth/google/callback",
})

plugin = GoogleOAuthPlugin.from_config(app.config)
app.plugins.load_plugin(plugin)

Advanced Usage

Custom Session Creation

def create_session_from_user(google_user):
    """Create a session from Google user data."""
    user = app_user_from_google(google_user)
    session_token = generate_session_token(user)
    return session_token

plugin = GoogleOAuthPlugin(
    client_id="...",
    client_secret="...",
    redirect_uri="...",
    session_maker=create_session_from_user,
    success_redirect="/dashboard",
)
app.plugins.load_plugin(plugin)

Custom User Mapping

def map_google_user(google_user):
    """Map Google user to app user model."""
    return {
        "external_id": google_user.id,
        "email": google_user.email,
        "email_verified": google_user.verified_email,
        "full_name": google_user.name,
        "first_name": google_user.given_name,
        "last_name": google_user.family_name,
        "avatar_url": google_user.picture,
        "locale": google_user.locale,
    }

plugin = GoogleOAuthPlugin(
    client_id="...",
    client_secret="...",
    redirect_uri="...",
    user_mapper=map_google_user,
)

Custom Scopes

# Request only what you need
plugin = GoogleOAuthPlugin(
    client_id="...",
    client_secret="...",
    redirect_uri="...",
    scopes=["openid", "email"],  # Just email, no profile
)

# Or request additional scopes
plugin = GoogleOAuthPlugin(
    client_id="...",
    client_secret="...",
    redirect_uri="...",
    scopes=[
        "openid",
        "email",
        "profile",
        "https://www.googleapis.com/auth/drive.readonly"
    ],
)

Protected Routes

from flaxon_oauth_google import login_required

@app.get("/profile")
@login_required
async def profile(request):
    user = request.session.get("user")
    return {
        "name": user.get("name"),
        "email": user.get("email"),
        "picture": user.get("picture"),
    }

@app.get("/settings")
@login_required
async def settings(request):
    return {"settings": "..."}

OAuth Endpoints

Route Method Description
/auth/google/login GET Redirect to Google consent screen
/auth/google/callback GET OAuth callback endpoint
/auth/google/logout GET Clear session (optional)
/auth/google/user GET Get current user info

Security Best Practices

✅ Store client secret in environment variables

✅ Use HTTPS in production

✅ Validate redirect URI matches registered URI

✅ Use state parameter for CSRF protection

✅ Verify ID token signature

✅ Keep scopes minimal (least privilege)

✅ Regenerate session ID on login

✅ Use secure cookies (Secure, HttpOnly, SameSite)

Example Application

Complete Setup

from flaxon import Flaxon
from flaxon_oauth_google import GoogleOAuthPlugin
import os

app = Flaxon("my-app")

# Load plugin
plugin = GoogleOAuthPlugin(
    client_id=os.environ["GOOGLE_CLIENT_ID"],
    client_secret=os.environ["GOOGLE_CLIENT_SECRET"],
    redirect_uri=f"{os.environ['APP_URL']}/auth/google/callback",
    scopes=["openid", "email", "profile"],
    success_redirect="/dashboard",
    failure_redirect="/login?error=oauth_failed",
)

def create_session(google_user):
    """Create a session for the user."""
    # Your session creation logic
    session_id = f"session_{google_user.id}_{int(time.time())}"
    return session_id

plugin.session_maker = create_session
app.plugins.load_plugin(plugin)

@app.get("/")
async def home(request):
    return """
    <html>
        <body>
            <h1>Welcome to My App</h1>
            <a href="/auth/google/login">
                <button>Sign in with Google</button>
            </a>
        </body>
    </html>
    """

@app.get("/dashboard")
async def dashboard(request):
    user = request.session.get("user")
    if not user:
        return {"error": "Not authenticated"}, 401
    return {
        "welcome": f"Hello, {user.get('name')}!",
        "email": user.get("email"),
        "picture": user.get("picture"),
    }

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)

Testing

# Run tests
pytest

# Run with coverage
pytest --cov=flaxon_oauth_google

# Run specific test
pytest tests/test_provider.py -v

Requirements

Python 3.11+

Flaxon 0.1.0+

httpx 0.27.0+

pyjwt 2.8.0+

cryptography 42.0.0+

Project Structure

flaxon-oauth-google/
├── pyproject.toml
├── README.md
├── LICENSE
├── src/
│   └── flaxon_oauth_google/
│       ├── __init__.py       # Public API exports
│       ├── plugin.py         # GoogleOAuthPlugin class
│       ├── provider.py       # GoogleOAuthProvider
│       ├── client.py         # Google API client
│       ├── user.py           # User info mapping
│       └── routes.py         # OAuth route handlers
└── tests/
    ├── test_plugin.py
    ├── test_provider.py
    └── test_integration.py

Roadmap

Version Features
0.1.0 Basic Google OAuth flow
0.2.0 G Suite domain restriction
0.3.0 Service account support
0.4.0 Social login buttons (HTML helpers)
0.5.0 Refresh token rotation

Contributing

Fork the repository

Create a feature branch

Add tests for new features

Ensure all tests pass

Submit a pull request

License

MIT License - See LICENSE file for details.

Support

📚 Documentation

🐛 Issue Tracker

💬 Discussions

Metadata

Release files for flaxon-oauth-google 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for flaxon-oauth-google 0.1.2
File Size Uploaded Provenance Actions
flaxon_oauth_google-0.1.2.tar.gz 18.0 kB Without provenance Details for flaxon_oauth_google-0.1.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for flaxon-oauth-google 0.1.2
File Interpreter ABI Platform Actions
flaxon_oauth_google-0.1.2-py3-none-any.whl Python 3 none any Details for flaxon_oauth_google-0.1.2-py3-none-any.whl

Total release size: 31.9 kB

Release files / flaxon_oauth_google-0.1.2.tar.gz

Download URL flaxon_oauth_google-0.1.2.tar.gz
Size 18.0 kB
Tags Source
SHA-256 checksum
How to use checksums
2d3861aa995f8d13f1dea17e57230729600c4ff236cbe0c7896ffadba49e8285
BLAKE2b-256 checksum
How to use checksums
487212239e250af614aff5181303673707d081111c573f8e4d59fd6ebeee50b2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.3

Release files / flaxon_oauth_google-0.1.2-py3-none-any.whl

Download URL flaxon_oauth_google-0.1.2-py3-none-any.whl
Size 13.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0ce146649871bbb1fe0f9acb621d7b0f489c8103f2ee0f3b16ce8989c4b484b7
BLAKE2b-256 checksum
How to use checksums
27d5bd4fc2db9bd1ed856a815579db560e4558e59ac7c5e344b0a4acd390f0df
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.3

Security for flaxon-oauth-google 0.1.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page