A modern, passwordless authentication gateway built with Astro, Turso, and Better Auth with support for multiple authentication methods and providers.
- π Passwordless Authentication
- Passkey (WebAuthn)
- Magic Link
- Email OTP
- π Two-Factor Authentication (2FA)
- π Session Management
- Apple
- GitHub
- Kakao
- Naver
- Line
- Yandex
- VK
- π₯ Organization Management - Multi-tenant support
- π API Key Management - Generate and manage API keys
- π Admin Panel - Administrative controls
- π OAuth Proxy - Custom OAuth provider support
- β±οΈ One-Time Tokens - Secure temporary access
- π OpenAPI Documentation - Auto-generated API docs
- Node.js 18+ or Bun
- Turso account (free at turso.tech)
bun install
# or
npm install# Install Turso CLI
curl -sSfL https://get.tur.so/install.sh | bash
# Create a database
turso db create auth-gateway
# Get database URL
turso db show auth-gateway --url
# Create auth token
turso db tokens create auth-gatewayCopy .env.example to .env and fill in your credentials:
cp .env.example .envRequired variables:
TURSO_DATABASE_URL=libsql://your-database.turso.io
TURSO_AUTH_TOKEN=your-auth-token
BETTER_AUTH_SECRET=your-secret-key-here-min-32-chars
BETTER_AUTH_URL=http://localhost:4321bun run db:migrate
# or
npm run db:migrateAdd your OAuth credentials to .env:
# Google
GOOGLE_CLIENT_ID=your-client-id
GOOGLE_CLIENT_SECRET=your-client-secret
# GitHub
GITHUB_CLIENT_ID=your-client-id
GITHUB_CLIENT_SECRET=your-client-secret
# Add more providers as needed...Google: Google Cloud Console
- Callback URL:
http://localhost:4321/api/auth/callback/google
GitHub: GitHub Developer Settings
- Callback URL:
http://localhost:4321/api/auth/callback/github
Facebook: Facebook Developers
- Callback URL:
http://localhost:4321/api/auth/callback/facebook
Apple: Apple Developer
- Callback URL:
http://localhost:4321/api/auth/callback/apple
bun dev
# or
npm run devVisit http://localhost:4321 to see the login gateway.
/
βββ public/ # Static assets
βββ src/
β βββ components/ # React components
β β βββ AuthButton.tsx
β β βββ LoginGateway.tsx
β βββ db/ # Database configuration
β β βββ client.ts # Kysely client
β β βββ schema.ts # TypeScript types
β β βββ migrate.ts # Migration script
β βββ lib/ # Utilities and configs
β β βββ auth.ts # Better Auth config
β β βββ auth-client.ts # Client-side auth
β β βββ utils.ts # Helper functions
β βββ pages/ # Astro pages
β βββ index.astro # Login page
β βββ dashboard.astro # User dashboard
β βββ api/auth/[...all].ts # Auth API routes
βββ .env.example # Environment template
βββ astro.config.mjs # Astro configuration
βββ tailwind.config.mjs # Tailwind CSS config
βββ package.json
| Command | Action |
|---|---|
bun install |
Install dependencies |
bun dev |
Start dev server at localhost:4321 |
bun build |
Build production site to ./dist/ |
bun preview |
Preview production build |
bun run db:migrate |
Run database migrations |
import { authClient } from './lib/auth-client';
// Magic Link
await authClient.magicLink.sendMagicLink({
email: 'user@example.com'
});
// Email OTP
await authClient.emailOTP.sendOTP({
email: 'user@example.com'
});
// Passkey Registration
await authClient.passkey.register();
// Passkey Sign In
await authClient.passkey.signIn();
// Enable 2FA
const { qrCode, secret } = await authClient.twoFactor.enable();
// Create API Key
const apiKey = await authClient.apiKey.create({
name: 'My API Key',
expiresIn: 90 // days
});
// Create Organization
const org = await authClient.organization.create({
name: 'My Company',
slug: 'my-company'
});// In Astro page
---
import { auth } from '../lib/auth';
const session = await auth.api.getSession({
headers: Astro.request.headers,
});
if (!session) {
return Astro.redirect('/');
}
---- Passwordless: No passwords to leak or forget
- Passkey Support: WebAuthn/FIDO2 hardware security
- 2FA: Time-based one-time passwords
- Session Management: Secure token-based sessions
- API Key Management: Scoped and expirable keys
- Rate Limiting: Built-in protection
- CSRF Protection: Automatic token validation
Once running, visit /api/auth/reference for the auto-generated OpenAPI documentation.
- Build the project:
bun run build-
Set environment variables in your hosting platform
-
Deploy the
dist/directory
- β
Set secure
BETTER_AUTH_SECRET(min 32 chars) - β
Update
BETTER_AUTH_URLto production URL - β Configure OAuth callback URLs
- β Set up email service for Magic Link/OTP
- β Enable rate limiting
- β Configure CORS if needed
Edit src/lib/auth.ts and add to the oAuthProxy plugin:
{
id: 'custom-provider',
name: 'Custom Provider',
authorizationUrl: 'https://...',
tokenUrl: 'https://...',
userInfoUrl: 'https://...',
clientId: process.env.CUSTOM_CLIENT_ID || '',
clientSecret: process.env.CUSTOM_CLIENT_SECRET || '',
scopes: ['profile', 'email'],
}The project uses Tailwind CSS. Customize colors and styles in tailwind.config.mjs or modify component classes directly.
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - feel free to use this in your projects!
Built with: