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

JackD's avatar

user access filtering

i have this code inside middleware/authenticate.php i tried to not allow to logged in those user's who do not yet verified their account via email

but when i tried this code below the user continue to logged in even their account is not yet verified via email, it supposed to stay on the login page with the session message to verify account first.

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

        if ($this->auth->guest())
        {
            if ($request->ajax())
            {
                return response('Unauthorized.', 401);
            }
            else
            {
                return redirect()->guest('auth/login');
            }
        }

        if (!\Auth::user()->active) {
            \Session::flash('message', 'Please activate your account to proceed.');
            return redirect()->guest('/home');
        }
        return $next($request);
    }

i also tried to change this from

return redirect()->guest('/home');

to

return redirect()->guest('auth/login');

but i got this message

This webpage has a redirect loop

0 likes
10 replies
alexwolff's avatar

@Ci A better way and easier way is to pass the desired state to your attempt method

This is the default postLogin from the AuthController from L5

public function postLogin (Request $request)
    {

        $this->validate($request, [
            'email' => 'required', 'password' => 'required',
        ]);

        $credentials = $request->only('email', 'password');
        $credentials['active'] = 1;

        if ($this->auth->attempt($credentials, $request->has('remember'))) {
            return redirect()->intended($this->redirectPath());
        }

        return redirect('admin/auth/login')
            ->withInput($request->only('email'))
            ->withErrors([
                'email' => 'These credentials do not match our records.'
            ]);
    }

Laravel will check if the "active" column on the users table is equal to 1

$credentials['active'] = 1;

Down side you cannot say why the authentication failed. You have to stick to default error message.

Or you could check it before redirecting with something like this

$user = User::whereEmail($credentials['email'])->get()
if($user AND ! $user->active) {
    \Session::flash('message', 'Please activate your account to proceed.');
}
JackD's avatar

@alexwolff doesn't work on me it still allow a user to logged in even if not yet verified

bobbybouwmann's avatar

Did you check if the active state is set in the database? Just to be sure!

JackD's avatar

@blackbird yes i have an "active" field on my users database now and i have a sample user their where the active is currently 0

usman's avatar

@Ci IMHO, you should separate the routes that require an active user and then apply a dedicated middleware on those routes. This way the user will only be redirected when they access an active middleware protected route and redirecting to home will not create a loop.

alexwolff's avatar

I use the same for my confirmation. If the users haven't confirmed their email address it won't allow them to log in.

Instead of active I have a confirmed flag in the db.

What type is the field? It has to be a tinyint. Or at least an Integer. String won't work. Or you update the code to

$credentials['active'] = '1';

Alex

JackD's avatar

@alexwolff it is working now i override the postLogin and change the data type of the field active.

but im getting this message when i tried

if($user AND ! $user->active){
 \Session::flash('message','Please activate your account to proceed');
}

Undefined property: Illuminate\Database\Eloquent\Collection::$active

alexwolff's avatar

Ups sorry use first() insted of get();

Get gives u a collection first only one model object

$user = User::whereEmail($credentials['email'])->first();
JackD's avatar

@alexwolff yes it is working now but i still have this

These credentials do not match our records. 

together with

Please activate your account to proceed

i also change this part from

       return redirect('admin/auth/login')
            ->withInput($request->only('email'))
            ->withErrors([
                'email' => 'These credentials do not match our records.'
            ]);

to

     return redirect($this->loginPath())
            ->withInput($request->only('email', 'remember'))
            ->withErrors([
                'email' => $this->getFailedLoginMessage(),
            ]);
JackD's avatar

i use this and it is ok now, please check if i have done wrong here but it is working now

thanks a lot guys

    public function postLogin (Request $request)
    {
        $this->validate($request,[
           'email'=>'required', 'password'=>'required',
        ]);
        $credentials = $request->only('email', 'password');
        $credentials['active'] = 1;

        if($this->auth->attempt($credentials, $request->has('remember'))){
            return redirect()->intended($this->redirectPath());
        }
        $user = User::whereEmail($credentials['email'])->first();
        if($user AND ! $user->active){
            \Session::flash('message','Please activate your account to proceed');
            return redirect('auth/login');
        } else {
            return redirect($this->loginPath())
                ->withInput($request->only('email', 'remember'))
                ->withErrors([
                    'email' => $this->getFailedLoginMessage(),
                ]);
        }
    }

Please or to participate in this conversation.