Authentication
KnowledgeCheckr uses Better Auth v1.2.5 for a flexible, secure authentication system supporting multiple providers and anonymous users.Overview
Better Auth provides:- Email/password authentication
- OAuth social providers (GitHub, Google, Dex)
- Anonymous user sessions
- Account linking
- Session management
- Rate limiting
Configuration
Location:src/lib/auth/server.ts
Basic Setup
Database Integration
Better Auth connects directly to MySQL using the connection pool:User- User accountsAccount- OAuth provider dataSession- Active sessionsVerification- Email verification tokens
Table Mapping
Authentication Methods
Email & Password
Configuration:- Minimum 8-character passwords
- Automatic sign-in after registration
- Password hashing (handled by Better Auth)
- Email verification support
Social Authentication
GitHub OAuth
- Name: GitHub username
- Email: Primary GitHub email
- Image: GitHub avatar URL
Google OAuth
- Name: Google account name
- Email: Google email
- Image: Google profile photo
Generic OAuth (Dex)
Support for custom OAuth providers via thegenericOAuth plugin:
mapProfileToUser function transforms the OAuth provider’s profile format into KnowledgeCheckr’s user schema.
Provider Initialization Utility
Dynamic provider configuration based on environment variables:Anonymous Authentication
Theanonymous plugin allows users to interact with the platform without registration.
Configuration
Anonymous User Flow
-
Creation: User accesses the site without signing in
- Better Auth creates a temporary user with
isAnonymous: true - Session is created and tracked via cookies
- Better Auth creates a temporary user with
-
Usage: Anonymous user can:
- Create knowledge checks (owned by anonymous user ID)
- Take practice sessions
- Take examinations (if allowed by check settings)
-
Account Linking: When anonymous user signs up/in:
onLinkAccountcallback is triggered- All owned checks are transferred to the new account
- All examination results are transferred
- Anonymous user record is deleted (cascade)
Data Migration Example
Fromsrc/lib/auth/server.ts:69-82:
Session Management
Server-Side Session Retrieval
Client-Side Session Retrieval
Better Auth provides React hooks (vianextCookies plugin):
Session Data Structure
src/lib/auth/server.ts:109:
Security Features
Rate Limiting
- Disabled in test mode for automated testing
- Enabled in development and production
- Protects against brute force attacks
- Applied to authentication endpoints
Session Security
Better Auth automatically handles:- Secure Cookies:
httpOnlyandsecureflags - CSRF Protection: Token-based protection
- Session Expiration: Automatic cleanup
- IP Tracking: Stored in
Session.ipAddress - User Agent Tracking: Stored in
Session.userAgent
Password Security
- Minimum 8 characters enforced
- Automatic hashing (bcrypt/argon2)
- No plaintext password storage
- Password reset via verification tokens
API Endpoints
Better Auth automatically creates API routes under/api/auth/*:
POST /api/auth/sign-up- Register new userPOST /api/auth/sign-in- LoginPOST /api/auth/sign-out- LogoutGET /api/auth/session- Get current sessionGET /api/auth/callback/:provider- OAuth callbacksPOST /api/auth/link-account- Link anonymous to authenticated
Integration with Next.js
Next.js Configuration
Fromnext.config.ts:5-7:
Middleware Setup
Better Auth integrates with Next.js middleware via thenextCookies plugin:
Authentication Guards
Server Component Guard
API Route Guard
Role-Based Access
Check ownership and collaboration:Logging
Authentication events are logged using Winston:- Development: Console output
- Production: Winston log files with daily rotation
Environment Variables
Required environment variables:Best Practices
- Always validate sessions server-side: Don’t trust client-side session data
- Use
getServerSession()in Server Components: Avoids unnecessary client-side fetches - Handle anonymous users gracefully: Check
user.isAnonymousbefore requiring registration - Enable rate limiting in production: Protects against abuse
- Log authentication events: Helps with debugging and security monitoring
- Transfer anonymous data on account linking: Preserve user’s work when they register
Troubleshooting
Sessions Not Persisting
- Verify cookie settings in browser (httpOnly, secure flags)
- Check that
nextCookies()plugin is enabled - Ensure session hasn’t expired
OAuth Provider Not Working
- Verify environment variables are set
- Check OAuth app configuration (redirect URIs, scopes)
- Review Better Auth logs for errors
Anonymous Account Linking Failed
- Check database foreign key constraints
- Verify
onLinkAccountcallback isn’t throwing errors - Review Winston logs for transfer errors
Next Steps
- Database Schema - User and session tables
- Architecture - Overall system design