Google OAuth 2.0 authentication plugin for Flaxon framework
Project description
Flaxon OAuth Google
Google OAuth 2.0 authentication plugin for Flaxon framework.
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
python
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
bash
# 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
python
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
python
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
python
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
python
# 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
python
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
python
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
bash
# 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
text
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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
flaxon_oauth_google-0.1.1.tar.gz
(16.4 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file flaxon_oauth_google-0.1.1.tar.gz.
File metadata
- Download URL: flaxon_oauth_google-0.1.1.tar.gz
- Upload date:
- Size: 16.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7c8229d72e9ab3faf0f5d92a55a6fd012d88bfa22d6493620d3ca9fd64198f23
|
|
| MD5 |
d1fdac80fbc7a26cf28ade8dc8a8a07f
|
|
| BLAKE2b-256 |
d0af3363f50d112f823b654ed4f037c8941d5b05823099e74509077c3c66365e
|
File details
Details for the file flaxon_oauth_google-0.1.1-py3-none-any.whl.
File metadata
- Download URL: flaxon_oauth_google-0.1.1-py3-none-any.whl
- Upload date:
- Size: 13.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5ba3a278ce12978fabed715cf4e3fc8ae75c80f0a9a8cf895e091ec4d699f0bc
|
|
| MD5 |
23153755e16fd0710650cb4d28e58d18
|
|
| BLAKE2b-256 |
7561a830a30644e893e6d5a5d73c82b792f5506b9aef5d3e67b5e778d8b95e1e
|