Auth Module
The Auth module provides a complete authentication and authorization system supporting JWT tokens, OAuth2 providers, API keys, role-based access control (RBAC), multi-factor authentication (MFA), and session management.
Configuration
example.py
python
Copied!
| 1 | from vorte import Vorte |
| 2 | |
| 3 | app = Vorte( |
| 4 | auto_load=True, |
| 5 | config={ |
| 6 | "auth": { |
| 7 | "secret_key": "${'${AUTH_SECRET_KEY}'}", |
| 8 | "algorithm": "HS256", |
| 9 | "access_token_ttl": 3600, |
| 10 | "refresh_token_ttl": 604800, |
| 11 | "oauth_providers": { |
| 12 | "google": { |
| 13 | "client_id": "${'${GOOGLE_CLIENT_ID}'}", |
| 14 | "client_secret": "${'${GOOGLE_CLIENT_SECRET}'}", |
| 15 | "redirect_uri": "http://localhost:8000/auth/callback/google", |
| 16 | }, |
| 17 | "github": { |
| 18 | "client_id": "${'${GITHUB_CLIENT_ID}'}", |
| 19 | "client_secret": "${'${GITHUB_CLIENT_SECRET}'}", |
| 20 | "redirect_uri": "http://localhost:8000/auth/callback/github", |
| 21 | }, |
| 22 | }, |
| 23 | "mfa": { |
| 24 | "enabled": True, |
| 25 | "issuer": "My Vorte App", |
| 26 | "backup_codes": 10, |
| 27 | }, |
| 28 | "sessions": { |
| 29 | "backend": "redis", |
| 30 | "ttl": 86400, |
| 31 | }, |
| 32 | }, |
| 33 | }, |
| 34 | ) |
JWT Authentication
login.py
python
Copied!
| 1 | from vorte.auth import Auth, create_token, decode_token |
| 2 | |
| 3 | auth = Auth() |
| 4 | |
| 5 | @router.post("/auth/login") |
| 6 | async def login(email: str, password: str): |
| 7 | user = await auth.authenticate(email, password) |
| 8 | if not user: |
| 9 | return error_response(code="INVALID_CREDENTIALS", status_code=401) |
| 10 | |
| 11 | access_token = create_token( |
| 12 | payload={"sub": user.id, "role": user.role}, |
| 13 | ttl=3600, |
| 14 | ) |
| 15 | refresh_token = create_token( |
| 16 | payload={"sub": user.id, "type": "refresh"}, |
| 17 | ttl=604800, |
| 18 | ) |
| 19 | return success_response(data={ |
| 20 | "access_token": access_token, |
| 21 | "refresh_token": refresh_token, |
| 22 | "token_type": "bearer", |
| 23 | }) |
| 24 | |
| 25 | @router.post("/auth/refresh") |
| 26 | async def refresh_token(refresh_token: str): |
| 27 | payload = decode_token(refresh_token) |
| 28 | access_token = create_token( |
| 29 | payload={"sub": payload["sub"], "role": payload.get("role")}, |
| 30 | ttl=3600, |
| 31 | ) |
| 32 | return success_response(data={"access_token": access_token}) |
OAuth2 Integration
google_login.py
python
Copied!
| 1 | from vorte.auth import OAuthManager |
| 2 | |
| 3 | oauth = OAuthManager() |
| 4 | |
| 5 | @router.get("/auth/google") |
| 6 | async def google_login(): |
| 7 | url = oauth.get_authorization_url("google") |
| 8 | return {"redirect_url": url} |
| 9 | |
| 10 | @router.get("/auth/callback/google") |
| 11 | async def google_callback(code: str): |
| 12 | user = await oauth.handle_callback("google", code) |
| 13 | token = create_token(payload={"sub": user.id, "role": user.role}) |
| 14 | return success_response(data={"access_token": token}) |
API Keys
create_api_key.py
python
Copied!
| 1 | from vorte.auth import APIKeyManager |
| 2 | |
| 3 | api_keys = APIKeyManager() |
| 4 | |
| 5 | @router.post("/api-keys") |
| 6 | async def create_api_key(name: str, scopes: list[str]): |
| 7 | key = await api_keys.create(name=name, scopes=scopes) |
| 8 | return success_response(data={"key": key, "name": name}) |
| 9 | |
| 10 | @router.delete("/api-keys/{key_id}") |
| 11 | async def revoke_api_key(key_id: str): |
| 12 | await api_keys.revoke(key_id) |
| 13 | return success_response(message="API key revoked") |
Role-Based Access Control (RBAC)
admin_list_users.py
python
Copied!
| 1 | from vorte.auth import RBAC, Role, Permission |
| 2 | |
| 3 | rbac = RBAC() |
| 4 | |
| 5 | rbac.define_role("admin", permissions=[ |
| 6 | Permission("users", "read"), |
| 7 | Permission("users", "write"), |
| 8 | Permission("users", "delete"), |
| 9 | Permission("settings", "read"), |
| 10 | Permission("settings", "write"), |
| 11 | ]) |
| 12 | |
| 13 | rbac.define_role("editor", permissions=[ |
| 14 | Permission("users", "read"), |
| 15 | Permission("content", "read"), |
| 16 | Permission("content", "write"), |
| 17 | ]) |
| 18 | |
| 19 | rbac.define_role("viewer", permissions=[ |
| 20 | Permission("users", "read"), |
| 21 | Permission("content", "read"), |
| 22 | ]) |
| 23 | |
| 24 | @router.get("/admin/users") |
| 25 | @rbac.require("users:read") |
| 26 | async def admin_list_users(user=Depends(auth.current_user)): |
| 27 | return success_response(data=await db.list_users()) |
Multi-Factor Authentication (MFA)
setup_mfa.py
python
Copied!
| 1 | from vorte.auth import MFA |
| 2 | |
| 3 | mfa = MFA() |
| 4 | |
| 5 | @router.post("/auth/mfa/setup") |
| 6 | async def setup_mfa(user=Depends(auth.current_user)): |
| 7 | secret = mfa.generate_secret(user.id) |
| 8 | qr_url = mfa.get_qr_code(user.id, secret, issuer="My Vorte App") |
| 9 | backup_codes = mfa.generate_backup_codes(count=10) |
| 10 | return success_response(data={ |
| 11 | "secret": secret, |
| 12 | "qr_url": qr_url, |
| 13 | "backup_codes": backup_codes, |
| 14 | }) |
| 15 | |
| 16 | @router.post("/auth/mfa/verify") |
| 17 | async def verify_mfa(code: str, user=Depends(auth.current_user)): |
| 18 | valid = mfa.verify_code(user.id, code) |
| 19 | if not valid: |
| 20 | return error_response(code="INVALID_MFA_CODE", status_code=401) |
| 21 | return success_response(message="MFA verified") |
Route Guards
Protect routes with declarative guards that check authentication and authorization before the handler executes.
get_profile.py
python
Copied!
| 1 | from vorte.auth import require_auth, require_role, require_scope |
| 2 | |
| 3 | @router.get("/profile") |
| 4 | @require_auth |
| 5 | async def get_profile(user=Depends(auth.current_user)): |
| 6 | return success_response(data=user) |
| 7 | |
| 8 | @router.delete("/users/{user_id}") |
| 9 | @require_role("admin") |
| 10 | async def delete_user(user_id: int): |
| 11 | await db.delete_user(user_id) |
| 12 | return success_response(message="User deleted") |
| 13 | |
| 14 | @router.post("/reports") |
| 15 | @require_scope("reports:write") |
| 16 | async def create_report(payload: ReportPayload): |
| 17 | report = await db.create_report(payload) |
| 18 | return success_response(data=report) |
Session Management
logout.py
python
Copied!
| 1 | from vorte.auth import SessionManager |
| 2 | |
| 3 | sessions = SessionManager(backend="redis") |
| 4 | |
| 5 | @router.post("/auth/logout") |
| 6 | @require_auth |
| 7 | async def logout(user=Depends(auth.current_user)): |
| 8 | await sessions.destroy(user.session_id) |
| 9 | return success_response(message="Logged out") |
| 10 | |
| 11 | @router.get("/auth/sessions") |
| 12 | @require_auth |
| 13 | async def list_sessions(user=Depends(auth.current_user)): |
| 14 | active = await sessions.list_active(user.id) |
| 15 | return success_response(data=active) |