F
Filament13mo ago
bwdev1

Different log-in behaviour depending on user role

Hi, I have two types of users - 'admin' and 'client'. I'd like to use the same log-in page for all users, however if the user is an 'admin', then they should be redirected to the filament dashboard on successful login (url is /admin which i think is the default behaviour of canAccessPanel), while clients should be redirected to their own dashboard (url /dashboard). The current code I have below doesn't work at the moment for clients, but it is a good starting point I believe. The issue with canAccessPanel is that on log in, clients are able to log in but are met with a
public function canAccessPanel(Panel $panel): bool
{
if ($panel->getId() === 'admin') {
if ($this->role == 'admin') {
return true;
}
if ($this->role == 'client') {
return false;
}
}
}
public function canAccessPanel(Panel $panel): bool
{
if ($panel->getId() === 'admin') {
if ($this->role == 'admin') {
return true;
}
if ($this->role == 'client') {
return false;
}
}
}
9 Replies
Quin.
Quin.13mo ago
if (auth()->user()->hasRole('admin') {
return true;
}
if (auth()->user()->hasRole('admin') {
return true;
}
i think you mean something like this
bwdev1
bwdev1OP13mo ago
$this->role seems to work just fine in my code, i've logged it and it returns the correct 'role' when logging in as either client or admin
Quin.
Quin.13mo ago
public function canAccessPanel(Panel $panel): bool
{
if (auth()->user()->hasRole('admin') {
return true;
}

if (auth()->user()->hasRole('client') {
return false;
}
}
public function canAccessPanel(Panel $panel): bool
{
if (auth()->user()->hasRole('admin') {
return true;
}

if (auth()->user()->hasRole('client') {
return false;
}
}
i think this should work fine why would you get the $panel->id?
ChesterS
ChesterS13mo ago
canAccessPanel is only to check what you have access to, it doesn't handle redirects (at least AFAIK) You'll need to handle this somewhere else. Do you only have one panel (the admin panel) ?
Quin.
Quin.13mo ago
public function canAccessPanel(Panel $panel): bool
{
if (auth()->user()->hasRole('admin') {
return true;
}

if (auth()->user()->hasRole('client') {
return redirect('VIEW');
}
}
public function canAccessPanel(Panel $panel): bool
{
if (auth()->user()->hasRole('admin') {
return true;
}

if (auth()->user()->hasRole('client') {
return redirect('VIEW');
}
}
tried the redirect?
bwdev1
bwdev1OP13mo ago
I've followed the documentation and kept it - i think it may be a bit reduntant as I only have 1 panel, so there is no need to check for its id, so i could get rid of it Youre right, and thats where my problem is - the default login behaviour is to try to redirect the user to the filament panel, so 'clients' are able to log in, but when they try to log in they are met with an error page. However if they navigate back to the homepage again, they will find themselves logged in. Hope that makes sense this function expects a boolean return so redirect causes an error
Quin.
Quin.13mo ago
my fault didn't pay attention to that detail
bwdev1
bwdev1OP13mo ago
no worries
bwdev1
bwdev1OP13mo ago
If comes across a similar problem , here is my solution, credits to guy from this thread https://laracasts.com/discuss/channels/general-discussion/filament-redirect-unauthenticated-and-non-admin-users-from-admin-to-a-certain-other-route : run
php artisan make:middleware RedirectIfNotFilamentAdmin
php artisan make:middleware RedirectIfNotFilamentAdmin
app/http/middleware/redirectifnotfilamentadmin.php:
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Filament\Facades\Filament;
use Filament\Models\Contracts\FilamentUser;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;

class RedirectIfNotFilamentAdmin
{
public function handle(Request $request, Closure $next)
{
$auth = Filament::auth();

if (!$auth->check()) {
return redirect(route('login'));
}

Auth::shouldUse(Filament::getAuthGuard());

/** @var Model $user */
$user = $auth->user();


$panel = Filament::getCurrentPanel();

if ($user instanceof FilamentUser) {

if ($user->role !== 'admin') {
return redirect(route('dashboard'));
}


if (!$user->canAccessPanel($panel) && config('app.env') !== 'local') {
return redirect(route('user.home'));
}
}

return $next($request);
}
}
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Filament\Facades\Filament;
use Filament\Models\Contracts\FilamentUser;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;

class RedirectIfNotFilamentAdmin
{
public function handle(Request $request, Closure $next)
{
$auth = Filament::auth();

if (!$auth->check()) {
return redirect(route('login'));
}

Auth::shouldUse(Filament::getAuthGuard());

/** @var Model $user */
$user = $auth->user();


$panel = Filament::getCurrentPanel();

if ($user instanceof FilamentUser) {

if ($user->role !== 'admin') {
return redirect(route('dashboard'));
}


if (!$user->canAccessPanel($panel) && config('app.env') !== 'local') {
return redirect(route('user.home'));
}
}

return $next($request);
}
}
Register this middleware in the AdminPanelServiceProvider change: ...->authMiddleware([ Authenticate::class, ]); To use App\Http\Middleware\RedirectIfNotFilamentAdmin; ...->authMiddleware([ RedirectIfNotFilamentAdmin::class, ]);
Laracasts
Want results from more Discord servers?
Add your server