Modern, secure authentication for Laravel 10/11 applications.
⚠️ DRAFT STATUS This package is currently in DRAFT status. The code exists and is functional, but has not been fully tested yet. We recommend waiting for v1.0.0 release before using in production. Current version: v0.1.0-beta
- Email/Password authentication with Argon2id hashing
- Magic Link passwordless authentication
- OAuth 2.0 (Google, GitHub, Facebook, Apple, Discord, Microsoft, Twitter/X)
- Passkeys/WebAuthn
- TOTP (Two-Factor Authentication)
- SSO/OIDC Provider
- Multi-Tenant (Organizations, Teams, Members, Invitations)
- UUID v7 support (time-ordered, non-guessable IDs)
- Laravel Facades and helpers
- Artisan commands for setup
- Middleware for route protection
- Event broadcasting
composer require betterauth/laravelRun the installation command:
php artisan better-auth:installThis will:
- Generate a secure secret key
- Publish configuration file (
config/better-auth.php) - Publish database migrations
- Optionally run migrations
- Add environment variables to
.env
Edit config/better-auth.php:
<?php
return [
// Choose between 'session' (monolith) or 'api' (stateless)
'mode' => env('BETTER_AUTH_MODE', 'api'),
'secret' => env('BETTER_AUTH_SECRET'),
// Session mode configuration
'session' => [
'lifetime' => 604800, // 7 days
'cookie_name' => 'better_auth_session',
],
// API mode configuration (Paseto V4 tokens)
'token' => [
'lifetime' => 7200, // Access token: 2 hours
'refresh_lifetime' => 2592000, // Refresh token: 30 days
],
// OAuth providers
'oauth' => [
'google' => [
'client_id' => env('GOOGLE_CLIENT_ID'),
'client_secret' => env('GOOGLE_CLIENT_SECRET'),
'redirect_uri' => env('GOOGLE_REDIRECT_URI'),
],
'github' => [
'client_id' => env('GITHUB_CLIENT_ID'),
'client_secret' => env('GITHUB_CLIENT_SECRET'),
'redirect_uri' => env('GITHUB_REDIRECT_URI'),
],
],
// Multi-tenancy
'multi_tenant' => [
'enabled' => false,
'default_role' => 'member',
],
];Add to .env:
BETTER_AUTH_MODE=api # or 'session' for traditional auth
BETTER_AUTH_SECRET=your-auto-generated-secret
# OAuth providers (optional)
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_REDIRECT_URI=http://localhost/auth/oauth/google/callback
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
GITHUB_REDIRECT_URI=http://localhost/auth/oauth/github/callbackphp artisan migrateThis creates the following tables:
users- User accounts (with UUID v7 or auto-increment IDs)sessions- User sessions (session mode)refresh_tokens- Refresh tokens (API mode)oauth_accounts- OAuth provider accountsorganizations- Organizations (multi-tenant)members- Organization membersinvitations- Member invitations
use BetterAuth\Laravel\Facades\BetterAuth;
// Register a user
$user = BetterAuth::register(
email: 'user@example.com',
password: 'SecurePassword123',
name: 'John Doe'
);
// Login (API mode)
$tokens = BetterAuth::login(
email: 'user@example.com',
password: 'SecurePassword123',
ipAddress: $request->ip(),
userAgent: $request->userAgent()
);
// Returns: ['accessToken' => '...', 'refreshToken' => '...', 'expiresIn' => 7200]
// Get current user
$user = BetterAuth::user();
// Check if authenticated
if (BetterAuth::check()) {
// User is authenticated
}
// Logout
BetterAuth::logout();
// Refresh token (API mode)
$newTokens = BetterAuth::refresh($refreshToken);// Get current user
$user = better_auth_user();
// Check if authenticated
if (better_auth_check()) {
// User is authenticated
}
// Get user ID
$userId = better_auth_id();<?php
namespace App\Http\Controllers;
use BetterAuth\Laravel\Facades\BetterAuth;
use Illuminate\Http\Request;
class AuthController extends Controller
{
public function register(Request $request)
{
$validated = $request->validate([
'email' => 'required|email|unique:users',
'password' => 'required|min:8',
'name' => 'required|string',
]);
$user = BetterAuth::register(
email: $validated['email'],
password: $validated['password'],
name: $validated['name']
);
return response()->json(['user' => $user], 201);
}
public function login(Request $request)
{
$validated = $request->validate([
'email' => 'required|email',
'password' => 'required',
]);
try {
$tokens = BetterAuth::login(
email: $validated['email'],
password: $validated['password'],
ipAddress: $request->ip(),
userAgent: $request->userAgent()
);
return response()->json($tokens);
} catch (\Exception $e) {
return response()->json(['error' => 'Invalid credentials'], 401);
}
}
public function me(Request $request)
{
$user = BetterAuth::user();
return response()->json(['user' => $user]);
}
public function refresh(Request $request)
{
$refreshToken = $request->input('refreshToken');
$tokens = BetterAuth::refresh($refreshToken);
return response()->json($tokens);
}
public function logout()
{
BetterAuth::logout();
return response()->json(['message' => 'Logged out successfully']);
}
}<?php
use App\Http\Controllers\AuthController;
use Illuminate\Support\Facades\Route;
Route::prefix('auth')->group(function () {
Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);
Route::post('/refresh', [AuthController::class, 'refresh']);
Route::middleware('better-auth')->group(function () {
Route::get('/me', [AuthController::class, 'me']);
Route::post('/logout', [AuthController::class, 'logout']);
});
});Protect your routes with the better-auth middleware:
Route::middleware('better-auth')->group(function () {
Route::get('/profile', [ProfileController::class, 'show']);
Route::post('/posts', [PostController::class, 'store']);
});Or in controllers:
class ProfileController extends Controller
{
public function __construct()
{
$this->middleware('better-auth');
}
public function show()
{
$user = better_auth_user();
return view('profile', compact('user'));
}
}use BetterAuth\Laravel\Facades\BetterAuth;
// Redirect to Google
Route::get('/auth/google', function () {
$url = BetterAuth::oauth('google')->getAuthorizationUrl();
return redirect($url);
});
// Handle callback
Route::get('/auth/google/callback', function (Request $request) {
$code = $request->get('code');
$userData = BetterAuth::oauth('google')->handleCallback($code);
// Create or update user
$user = BetterAuth::createOrUpdateOAuthUser($userData);
// Login user
$tokens = BetterAuth::loginOAuth($user);
return response()->json($tokens);
});- GitHub
- Apple
- Discord
- Microsoft
- Twitter/X
Enable multi-tenancy in config/better-auth.php:
'multi_tenant' => [
'enabled' => true,
'default_role' => 'member',
],Usage:
use BetterAuth\Laravel\Facades\BetterAuth;
// Create organization
$org = BetterAuth::organization()->create(
name: 'Acme Inc',
slug: 'acme-inc',
ownerId: $userId
);
// Invite member
BetterAuth::organization()->invite(
organizationId: $org->id,
email: 'member@example.com',
role: 'admin'
);
// Accept invitation
BetterAuth::organization()->acceptInvitation($token);
// List user's organizations
$organizations = BetterAuth::organization()->listForUser($userId);
// Get organization members
$members = BetterAuth::organization()->getMembers($org->id);BetterAuth for Laravel uses time-ordered UUIDs (UUID v7) by default:
$user = BetterAuth::register(...);
echo $user->id; // "019ab13e-40f1-7b21-a672-f403d5277ec7"Benefits:
- Chronologically sortable
- Non-guessable (secure)
- No index fragmentation (fast database queries)
- Compatible with distributed systems
Generated using Laravel's Str::orderedUuid()
# Install BetterAuth
php artisan better-auth:install
# Publish configuration
php artisan vendor:publish --tag=better-auth-config
# Publish migrations
php artisan vendor:publish --tag=better-auth-migrations
# Generate secret key
php artisan better-auth:generate-secretBetterAuth dispatches Laravel events:
use BetterAuth\Laravel\Events\UserRegistered;
use BetterAuth\Laravel\Events\UserLoggedIn;
use BetterAuth\Laravel\Events\UserLoggedOut;
// Listen to events
Event::listen(UserRegistered::class, function ($event) {
// Send welcome email
Mail::to($event->user)->send(new WelcomeEmail($event->user));
});
Event::listen(UserLoggedIn::class, function ($event) {
// Log user login
Log::info("User logged in: {$event->user->email}");
});
⚠️ IMPORTANT: This package currently lacks comprehensive tests. Tests are being written and will be included in v1.0.0 release.
# Run tests (when available)
composer test
# Run tests with coverage
composer test:coverage- PHP 8.2 or higher
- Laravel 10.0 or 11.0+
- Illuminate/Database ^10.0|^11.0
- Illuminate/Support ^10.0|^11.0
- Complete test suite (PHPUnit)
- Integration tests with Laravel 10 and 11
- Documentation improvements
- Example application
- Performance benchmarks
- Security audit
Contributions are welcome! Please see CONTRIBUTING.md for details.
Help needed:
- Writing comprehensive tests
- Testing with Laravel 10 and 11
- Documentation improvements
- Bug reports and feature requests
If you discover any security-related issues, please email security@betterauth.com instead of using the issue tracker.
The MIT License (MIT). Please see License File for more information.