Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ruffsaint's avatar

User / Admin authentication

Please can some please help by telling me how to go about designing a user and admin authentication application. since we have just one auth.

0 likes
35 replies
mstnorris's avatar

Use Middleware.

I have included a basic implementation and requires that you add an admin column to your users table. I'm not suggesting that this is the best way. I personally have set up Users, Roles, and Permissions but the example below will get you started.

  1. The following command creates new Middleware called Admin
php artisan make:middleware Admin
  1. This creates a file called Admin.php within the app/Http/Middleware directory that looks like
<?php namespace App\Http\Middleware;

use Closure;

class Admin {

    public function handle($request, Closure $next)
    {

        if ( Auth::check() && Auth::user()->isAdmin() )
        {
            return $next($request);
        }

        return redirect('home');

    }

}
  1. You then need to add the Admin Middleware to your app/Http/Kernel.php file
protected $routeMiddleware = [
    'auth' => 'App\Http\Middleware\Authenticate',
    'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
    'guest' => 'App\Http\Middleware\RedirectIfAuthenticated',
    'admin' => 'App\Http\Middleware\Admin', // this line right here
];
  1. Add the Admin Middleware to a route. (Within your routes.php file).
get('protected', ['middleware' => ['auth', 'admin'], function() {
    return "this page requires that you be logged in and an Admin";
}]);
  1. Finally you need to add the isAdmin method we created above to your User model to check whether or not the user is an Admin.
public function isAdmin()
{
    return $this->admin; // this looks for an admin column in your users table
}
  1. This will do the trick. If you run into any problems, please post what you have tried and which step you got up to and I'll try my best to help.
24 likes
martinbean's avatar

@mstnorris If you use attribute casting, you don’t need to explicitly return true or false from your isAdmin method in your User model:

class User extends Model
{
    protected $casts = [
        'is_admin' => 'boolean',
    ];

    public function isAdmin()
    {
        return $this->is_admin;
    }
}
mstnorris's avatar

Of course, nothing wrong but a few more characters. Corrected now :)

1 like
ruffsaint's avatar

@mstnorris am i using the same auth/login and auth/register for my view or i will create for admin

mstnorris's avatar

Yes you use the same login form, nothing changes on that part.

Just add a new field admin to your users table and follow the above and you're good to go.

ruffsaint's avatar

@mstnorris is the route like this get('protected', ['middleware' => ['auth', 'admin'], function() { return "this page requires that you be logged in and an Admin"; }]);

or

Route:get('protected', ['middleware' => ['auth', 'admin'], function() { return "this page requires that you be logged in and an Admin"; }]);

mstnorris's avatar

They are the same thing. The following do the same thing!

Route::get( ... );
get( ... );
$router->get( ... );
1 like
ruffsaint's avatar

@mstnorris av don everything.

my admin and user are going to have different view how am i going about that

mstnorris's avatar

@ruffsaint Then set up two different views and routes to respond to that.

get('protected', ['middleware' => ['auth', 'admin'], function() {
    // this page requires that you be logged in AND be an Admin
    return view( ... );
}]);

get('protected', ['middleware' => ['auth'], function() {
    // this page requires that you be logged inbut you don't need to be an admin
    return view( ... );
}]);
2 likes
ruffsaint's avatar

@mstnorris My Route

/* |-------------------------------------------------------------------------- | Application Routes |-------------------------------------------------------------------------- | | Here is where you can register all of the routes for an application. | It's a breeze. Simply tell Laravel the URIs it should respond to | and give it the controller to call when that URI is requested. | */

Route::get('/', 'WelcomeController@index');

Route::get('home', 'HomeController@index');

Route::controllers([ 'auth' => 'Auth\AuthController', 'password' => 'Auth\PasswordController', ]);

Route:get('protected', ['middleware' => ['auth', 'admin'], function() { return "this page requires that you be logged in and an Admin"; }]);

ruffsaint's avatar

@mstnorris Kernel

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel {

/**
 * The application's global HTTP middleware stack.
 *
 * @var array
 */
protected $middleware = [
    'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
    'Illuminate\Cookie\Middleware\EncryptCookies',
    'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
    'Illuminate\Session\Middleware\StartSession',
    'Illuminate\View\Middleware\ShareErrorsFromSession',
    'App\Http\Middleware\VerifyCsrfToken',
];

/**
 * The application's route middleware.
 *
 * @var array
 */

protected $routeMiddleware = [
    'auth' => 'App\Http\Middleware\Authenticate',
    'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
    'guest' => 'App\Http\Middleware\RedirectIfAuthenticated',
    'admin' => 'App\Http\Middleware\Admin', // this line right here
];

}

mstnorris's avatar

@ruffsaint what do you mean what controller should you use?

The code I gave you routes to a closure. If you want to change it to use controllers then do

get('admin', ['as' =>'admin.page', 'uses' => 'PagesController@admin', 'middleware' => ['auth', 'admin']]);

get('protected', ['as' =>'secure.page', 'uses' => 'PagesController@secure', 'middleware' => 'auth']);
ruffsaint's avatar

@mstnorris

use Closure;

class Admin {

/**
 * Handle an incoming request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Closure  $next
 * @return mixed
 */
public function handle($request, Closure $next)
{

    if ( Auth::check() && Auth::user()->isAdmin() )
{
    return $next($request);
}

    return redirect('home');
}

}

ruffsaint's avatar

@mstnorris

use Closure;

class Admin {

/**
 * Handle an incoming request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Closure  $next
 * @return mixed
 */
public function handle($request, Closure $next)
{

    if ( Auth::check() && Auth::user()->isAdmin() )
{
    return $next($request);
}

    return redirect('home');
}

}

ruffsaint's avatar

@mstnorris I thank you for ur help but am so lost now. whats ur email address pls maybe i can just send it to u. plssssssssssss

mstnorris's avatar

Yeah it is a forwarder so I receive all mail to that address.

varundavda's avatar

Hi @mstnorris

I have used this technique but i am not able to get the output i need.

There are two types of user.

  1. Admin
  2. Public Users.

I have a field in users table named 'is_admin'.

I want that if the user who logged in is admin then it should be redirected to different path and if he is public user then he should be redirected to a different path.

My users model looks like this.

<?php

namespace App;

use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;

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

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

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

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

    public function getUserSku(){

        return $this->belongsToMany('App\sku')->withTimestamps();

    }

    public function isAdmin()
    {
        return $this->admin; // this looks for an admin column in your users table
    }
}

My controller with middleware looks like this.

<?php

namespace App\Http\Controllers;

use App\subsribe;
use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Input;
use yajra\Datatables\Datatables;

class subscribeController extends Controller
{

    /**
     * Checks for authentication
    */

    public function __construct(){

        $this->middleware('auth' ,['except' => 'create']);

    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return view('admin.subscribe.index');
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {

        $email = Input::get('email');

        $check = subsribe::where('email','=',$email)->first();

        if($check === null){

            $subscribe = new subsribe;

            $subscribe->email = $email;

            $subscribe->save();

            return Response::json(array(
                'success' => true,
                'msg' => 'Thank you for subscribing.We hate spam too.'
            ));

        }else{

            return Response::json(array(
                'success' => false,
                'msg' => 'Thank you for love, but you have already subscribed with us.'
            ));

        }

    }

    public function getListing(){

        $subscribers = subsribe::select(['id', 'email','total_subscription_received'])->get();

        return Datatables::of($subscribers)->make(true);

    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
}

My RedirectUsers.php looks like this.


<?php

namespace Illuminate\Foundation\Auth;

use Illuminate\Support\Facades\Auth;

trait RedirectsUsers
{
    /**
     * Get the post register / login redirect path.
     *
     * @return string
     */
    public function redirectPath()
    {
        if (property_exists($this, 'redirectPath')) {
            return $this->redirectPath;
        }   

        $auth_check = Auth::user()->is_admin;
        
        if($auth_check == "yes" or Auth::user()->is_admin){

            return property_exists($this, 'redirectTo') ? $this->redirectTo : '/admin/homeInformation/1';

        }

        return property_exists($this, 'redirectTo') ? $this->redirectTo : '/';
    }
}
`

My  Admin.php in middleware looks like this.

`<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class Admin
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ( Auth::check() && Auth::user()->isAdmin() )
        {

            return $next($request);

        }else{

            return redirect ('auth/login/');

        }

    }
}

My kenrel.php under HTTP looks like this.


<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * @var array
     */
    protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
//        \App\Http\Middleware\VerifyCsrfToken::class,
    ];

    /**
     * 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\Admin',
    ];
}

Now what is happening is that even when a user who is not a admin is able to access the admin section.

When i change the controller middleware with 'admin' instead of 'auth' it redirects me to '/' instead of '/admin/{path}'

Shoaib's avatar

I am having the same problem like @ruffsaint

Please help me how i can use user table for both user login and admin login using middleware. Now i have done something but its not working correctly. I am using make:auth authentication with laravel 5.2

GrahamMorbyDev's avatar

Should the admin part of the db just have a true statement in the field?

larafever's avatar

Can anyone help me with the middleware , controllers and other syntax to implement if user and admin have separate models that contain their respective auth credentials

RyanThePyro's avatar

@ruffsaint maybe checkout how we do it in PyroCMS. The users module extends Laravel directly and I've added authentication extensions to handle different auth strategies. If I get what you're asking - it'd be a good place to look at some code.

https://github.com/anomalylabs/users-module https://github.com/anomalylabs/default_authenticator-extension

If you wanna install it to snoop around check out http://pyrocms.com/docs

Bulk of Users stuff will be in core/anomaly/users-module after you're all setup.

larafever's avatar

@ruffsaint i think i have a solution for user/admin auth from different models and views with each login view protection after auth check......................................................

first go the CONFIG->AUTH.PHP and the following code in the GUARDS ARRAY

  'admin' => [
            'driver' => 'session',
            'provider' => 'admins',
        ],

tthen in the PROVIDERS ARRAY in AUTH.PHP add

  'admins' => [
            'driver' => 'eloquent',
            'model' => App\Admin::class,
        ]

** note: the model can be changed to table then you specify you table name in the db or you can still use the model then specify your model for your admin

then in your ADMIN model use this

<?php

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;

class Admin extends Authenticatable
{

}

you have to create a middleware for your admin pages/routes you can use this to protect your login page and after login pages...


<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class AdminGuard
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $guard
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = 'admin')
    {
        if (Auth::guard($guard)->guest()) {
            if ($request->ajax() || $request->wantsJson())
                return response('Unauthorized.', 401);
                return redirect()->route('admin');//redirect to admin login;
            }
        return $next($request);
    }
}

then you can use a redirect if authenticated already to admin dashboard


<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class AdminRedirect
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $guard
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = 'admin')
    {
        if (Auth::guard($guard)->check()) {
            return redirect()->route('add');
        }

        return $next($request);
    }
}

in your controller you can use a simple auth::attempt to log your admin in

        if (Auth::guard('admin')->attempt(['username'=>$request['username'],'password'=>$request['password']]))
          return redirect()->route('add');
          return redirect()->back();

***NOTE THAT AFTER ADMIN LOGIN OR AUTH::ATTEMPT == TRUE, USER LOGIN ROUTE IS STILL ACCESSIBLE BUT PROTECTED AND ALL ROUTES UNDER THE USER/AUTH MIDDLEWARE IS STILL PROTECTED

1 like
anilpulikkoden's avatar

I am getting this error -

Type error: Argument 1 passed to Illuminate\Auth\SessionGuard::login() must implement interface Illuminate\Contracts\Auth\Authenticatable, instance of Illuminate\Database\Eloquent\Collection given, called in /home/vagrant/Code/Laravel/vendor/laravel/framework/src/Illuminate/Foundation/Auth/RegistersUsers.php on line 35

Any ideas?

vipin93's avatar

search "multi auth" on YouTube a Devmarketer channel he explained very welled

Mega's avatar

can models share the same auth middleware since mine here seems to be problematic

Next

Please or to participate in this conversation.