In certain applications, such as client portals or dashboards, you may want to allow users to access your Laravel Filament panel via a unique URL (different URL for different users) and authenticate using a PIN instead of traditional email/password login.
In this tutorial, we’ll walk through how to implement a PIN-based login system per user.
Use Case
We have:
- A Filament panel named
app
- Each user should get a unique login URL like
/app/user-slug
- When accessed, a PIN-based login page should appear
- After login, the client is redirected to
/app/dashboard
Step 1: Create Custom PIN-Based Login Page
Create a Blade view, for example:resources/views/filament/app/auth/pin-login.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>User Login</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
</head>
<body class="bg-gray-100 flex items-center justify-center min-h-screen">
<form method="POST" action="{{ url()->current() }}" class="bg-white p-6 rounded shadow-md w-full max-w-sm">
@csrf
<h2 class="text-lg font-semibold mb-4">Login for {{ $user->name }}</h2>
<label for="pin" class="block text-sm font-medium text-gray-700 mb-1">PIN</label>
<input type="password" name="pin" id="pin"
class="w-full px-3 py-2 border border-gray-300 rounded shadow-sm focus:outline-none focus:ring focus:ring-blue-300"
required autofocus />
@error('pin')
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
@enderror
<button type="submit"
class="w-full mt-4 bg-blue-600 text-white py-2 rounded hover:bg-blue-700">
Login
</button>
</form>
</body>
</html>
Step 2: Create Controller to handle PIN based login
Run the following command to create a controller file:
php artisan make:controller AppLoginController
It will create app/Http/Controllers/AppLoginController.php
file. Add the following code to this file.
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Filament\Facades\Filament;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Session;
class AppLoginController extends Controller
{
public function showLoginForm(string $slug)
{
if (Auth::guard('app')->check()) {
return redirect()->to(
route('filament.app.pages.dashboard')
);
}
$user = User::where('slug', $slug)->firstOrFail();
return view('filament.auth.app-login', compact('user'));
}
public function login(Request $request, $slug)
{
$user = User::where('slug', $slug)->firstOrFail();
$request->validate([
'pin' => 'required',
]);
if (!Hash::check($request->pin, $user->password)) {
return back()->withErrors(['pin' => 'Invalid PIN']);
}
Auth::guard('app')->login($user);
Session::put('redirect_after_logout', '/login/'.$slug);
return redirect()->to(
route('filament.app.pages.dashboard')
);
}
public function logout(Request $request)
{
$slug = auth('app')->user()->slug;
Filament::auth()->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect()->to(route('app.login', ['slug' => $slug]));
}
}
In above code, there are 3 functions. These functions details are as follows,
showLoginPage(string $slug)
This function is used for displaying custom PIN based login page. You can see that, it is displaying the same view coded above.
In same code, you can also check that if user is already logged in, you can redirect the user to the dashboard page.login(Request $request, $slug)
This function is processing the login, after user submit the login form using PIN. It checks the database with provided PIN and display proper message or redirect user to dashboard page on valid PIN.logout(Request $request)
It is a custom logout. We need this function, because all login pages have different URL based on user slug. So, whoever logout the app, should redirect to same URL, from where they started.
Step 3: Fix Logout Redirection
By default, Filament redirects to /app/login
after logout. If this route doesn’t exist, you’ll see an error.
To override this, we defined our own logout logic to intercept the logout redirection in above controller code. But, we also need to change the route to use this code for logout. So, append the following code to your routes/web.php
file.
Route::post('/auth/logout', [AppLoginController::class, 'logout'])->name('filament.app.auth.logout');
In above code, route name is important. Route name for the logout must be in filament.{panel-name}.auth.logout
. Here, {panel-name}
should be your panel name, which is app
in our case.
Conclusion
With this setup, your Laravel Filament application now supports:
- Unique user login URLs
- PIN-based authentication
- Redirect to the correct Filament panel (
/app/dashboard
)
This approach is clean, secure, and provides a delightful experience to your users.
Let me know in the comments if you’d like a reusable Livewire component or to implement branding per client!