Search code examples
phplaravellaravel-5laravel-authorizationlaravel-authentication

Middleware not following the condition - Laravel 5.7


I am trying to implement a user registration system in Laravel 5.7 where I am facing an issue.

I have two tables for Users- Admin(created by copying default Laravel auth), new routes, new middleware for admin. Every thing works fine while using guards.

I was trying to limit the user login by adding Approve/Disapprove functionality.

I added an extra column - admin(boolean) to the Users table.

In Login controller - LoginController.php Page, I added

  protected function authenticated($request, $user)
    {
        if ( $request->user()->admin != 1)
        // if($user->admin != 1)
        {
            return redirect()->route('approval');
        }
        else
        {
            return redirect('/engineer');
        }
    }

so that, when the admin is 1 I am directed to '/engineer' where as in other case I am directed to 'approval'.

It works as desired!.

Issue I am now facing is that if I try to access the 'engineer' using user whose not approved I am able to access the page. I am not sure how to restrict it. The page is still restricted to public.

Since the controller will be accessed by both the user and admin, I used __construct in the controller

web.php

Route::resource('engineer', 'engineerController');

engineerController.php

public function __construct()
        {
            $this->middleware('auth:web,admin');
        }

My Understanding is that the condition is only checked when the user logs in and there after its exits.

Do I need to create a new middle ware in order to keep the authorised page intact?

I am a self learner and new to laravel. I am pretty sure that I am not following the right practice. I started something and was trying to follow it till I finish. Please guide me through it.

Along with it please let me how could I have done it better.


Solution

  • You would need to define a Middleware that would check if the Engineer is approved or not. Obviously, you would also need to keep that in an is_approved column for example.

    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    
    class CheckEngineerApproval
    {
        /**
        * Handle an incoming request.
        *
        * @param  \Illuminate\Http\Request  $request
        * @param  \Closure  $next
        * @return mixed
        */
        public function handle($request, Closure $next)
        {
            if (! auth()->user->is_approved) {
                return redirect('user.approve');
            }
    
            return $next($request);
        }
    }
    

    Then, add it in your $routeMiddleware array in your Kernel.

    protected $routeMiddleware = [
        // 
        //
        'engineer.approved' => \App\Http\Middleware\CheckEngineerApproval::class,
    ];
    

    Finally, you can add the Middleware in your Controller's constructor as well.

    public function __construct()
    {
        $this->middleware(['auth:web','admin','engineer.approved']);
    }