SangminKim's avatar

User authentication custom middleware

A user has one of three roles: admin / owner / member and I'd like to allow only owners to use a specific route.

// Controller
class OwnerRestaurantController extends Controller
{
    public function __construct()
    {
        $this->middleware('owner');
    }
// Models
<?php

namespace App\Models;

use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;

class User extends Model implements AuthenticatableContract, CanResetPasswordContract
{
    use Authenticatable, CanResetPassword;

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'user';

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = ['password', 'remember_token'];

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'role_id',
        'email',
        'password',
        'name',
        'remember_token',
        'is_active',
        'created_at',
        'updated_at'
    ];


    public function restaurants()
    {
        return $this->hasMany('App\Models\Restaurant');
    }

    public function isAdmin()
    {
        return ($this->role_id == 1);

    }
    public function isOwner()
    {
        return ($this->role_id == 2);
    }
    public function isMember()
    {
        return ($this->role_id == 3);
    }
}
//Kernel
    /**
     * The application's route middleware.
     *
     * @var array
     */
    protected $routeMiddleware = [
        'auth'       => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'guest'      => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'admin'      => \App\Http\Middleware\AdminAuthenticated::class,
        'owner'      => \App\Http\Middleware\OwnerAuthenticated::class,
        'member'     => \App\Http\Middleware\MemberAuthenticated::class,
    ];
//Middleware

<?php

namespace App\Http\Middleware;

use Closure;
class OwnerAuthenticated
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        // This gets null cuz it doesn't know which user id to check...
        // Probably I can do... if(Auth::user()->role_id != 2(which is an owner id)) ..... but this code seems to smell bad somehow... :(

        if ($request->user()->isOwner()) {
            return redirect('home');
        }

        return $next($request);
    }
}

When OwnerAuthenticated middleware runs, I wanna call isOwner function in User model class to see if he is an owner or not but i'm having a trouble hence this middleware stuff is new to me.

What would be the best way to code it?

Thanks.

0 likes
4 replies
Bloomanity's avatar
Level 22
if(auth()->check() && auth()->user()->isOwner()) {
    return $next($request);
}

return redirect('home');

Try that one

2 likes
SangminKim's avatar

Beautiful ! Not only you've given me a working code but also corrected that if condition mistake lol. Thanks a lot.

1 like
jamalali's avatar

Great thread this is!

1 question though. How would you check for isAdmin, isOwner, isMember in a blade template?

Please or to participate in this conversation.