Quick Start
This guide walks you through running the demo applications to quickly experience OAuth2 and WebAuthn/Passkey authentication.
Prerequisites
- Rust toolchain: Latest stable version
- Web browser: Chrome (recommended, fewest issues), Android Chrome, or iOS Safari
Running Demo Applications
The repository includes several demo applications to showcase different authentication scenarios.
demo-both (OAuth2 + Passkey)
A complete authentication example showcasing both Google OAuth2 and WebAuthn/Passkey authentication in a single integrated application.
Features:
- Dual authentication methods (Google OAuth2 and WebAuthn/Passkey)
- Session management with CSRF protection
- User management and registration
- Admin interface for user administration
Setup
-
Choose Your ORIGIN
Decide how you’ll access the application:
- localhost (default):
http://localhost:3001- for local desktop testing (localhost is a secure context) - tunnel (mobile testing): Use Cloudflare Tunnel to get a public URL like
https://random-name.trycloudflare.com
Note: If using a tunnel, set it up first to get your URL before proceeding.
- localhost (default):
-
Get Google OAuth2 Credentials
- Go to Google Cloud Console
- Create OAuth2 credentials (Web application)
- Add
{YOUR_ORIGIN}/o2p/oauth2/authorizedto “Authorized redirect URIs”- For localhost:
http://localhost:3001/o2p/oauth2/authorized - For tunnel:
https://random-name.trycloudflare.com/o2p/oauth2/authorized
- For localhost:
- Copy the Client ID and Client Secret
-
Environment Setup
cd demo-both cp ../dot.env.simple .envEdit
.envwith your configuration:# Required: Base URL of your application (must match step 1) ORIGIN='http://localhost:3001' # Required: Google OAuth2 credentials (from step 2) OAUTH2_GOOGLE_CLIENT_ID='your-client-id.apps.googleusercontent.com' OAUTH2_GOOGLE_CLIENT_SECRET='your-client-secret' # Database (SQLite for easy setup) GENERIC_DATA_STORE_TYPE=sqlite GENERIC_DATA_STORE_URL='sqlite:/tmp/auth.db' # Cache (in-memory for demo) GENERIC_CACHE_STORE_TYPE=memory GENERIC_CACHE_STORE_URL='memory' -
Run the Demo
cargo runThe application starts on:
- HTTP: Port 3001 (access as
http://localhost:3001)
Note: localhost is a secure context, so WebAuthn/Passkey works over HTTP. For production, use a reverse proxy (nginx/Caddy) to provide HTTPS.
- HTTP: Port 3001 (access as
-
Try the Demo
- Visit your ORIGIN URL (e.g.,
http://localhost:3001or your tunnel URL) - Create a user with Google OAuth2 or Passkey
- Navigate to the user account page:
{YOUR_ORIGIN}/o2p/user/account - Add new Passkey or OAuth2 account
- Log out and sign in with a different method
- Explore credential linking and protected pages (p1-p6)
- Admin features: The first user gets admin privileges at
{YOUR_ORIGIN}/o2p/admin/index
- Visit your ORIGIN URL (e.g.,
Other Demo Applications
| Demo | Description | Notes |
|---|---|---|
| demo-oauth2 | OAuth2-only authentication | Simpler setup, no passkey |
| demo-passkey | Passkey-only authentication | No Google credentials needed |
| demo-custom-login | Custom login/summary pages | See Custom Pages |
| demo-profile | User profile extension | Bio, avatar, theme |
| demo-todo | App data linked to users | CRUD with user isolation |
| demo-cross-origin | Cross-Origin Same-Site (Pattern 2) | Auth + API servers |
Setup is similar to demo-both: copy .env from dot.env.simple, adjust for each demo’s needs.
Basic Configuration
Common Environment Variables
| Variable | Required | Description |
|---|---|---|
ORIGIN | Yes | Base URL of your application (e.g., http://localhost:3001) |
OAUTH2_GOOGLE_CLIENT_ID | For OAuth2 | Google OAuth2 client ID |
OAUTH2_GOOGLE_CLIENT_SECRET | For OAuth2 | Google OAuth2 client secret |
GENERIC_DATA_STORE_TYPE | Yes | Database type: sqlite or postgresql |
GENERIC_DATA_STORE_URL | Yes | Database connection URL |
GENERIC_CACHE_STORE_TYPE | Yes | Cache type: memory or redis |
GENERIC_CACHE_STORE_URL | Yes | Cache connection URL |
Development vs Production
Development (SQLite + Memory)
GENERIC_DATA_STORE_TYPE=sqlite
GENERIC_DATA_STORE_URL='sqlite:./auth.db'
GENERIC_CACHE_STORE_TYPE=memory
GENERIC_CACHE_STORE_URL='memory://demo'
Production (PostgreSQL + Redis)
GENERIC_DATA_STORE_TYPE=postgresql
GENERIC_DATA_STORE_URL='postgresql://user:pass@localhost/dbname'
GENERIC_CACHE_STORE_TYPE=redis
GENERIC_CACHE_STORE_URL='redis://localhost:6379'
To start PostgreSQL and Redis with Docker:
cd db && docker compose up -d
Troubleshooting
Common Issues
-
“Invalid origin” error
- Ensure
ORIGINin.envmatches the URL you’re visiting exactly - Use
http://localhost:3001(not127.0.0.1)
- Ensure
-
Google OAuth2 not working
- Check your Google OAuth2 credentials in
.env - Verify authorized origins and redirect URIs in Google Cloud Console
- Check your Google OAuth2 credentials in
-
WebAuthn/Passkey not working
- WebAuthn requires a secure context (localhost or HTTPS)
- Try a different browser (Chrome has the best WebAuthn support)
- Clear browser data for localhost if needed
-
“Authenticator not found” error
- Ensure your device has biometric capabilities enabled
- Try using a security key if available
-
Database errors
- SQLite database is created automatically
- Delete the database file to reset:
rm auth.db - Ensure the path in
GENERIC_DATA_STORE_URLis writable
Development Tips
- Logs: Check console output for detailed error messages
- Reset database: Delete
auth.dbto clear all sessions and credentials