0

There are several similar questions but all of them seem incomplete as they are referring to not existing functions.

I am referring to:

Check for active user state with laravel

Login only if user is active using Laravel

extend laravel 5 built-in authentication to login only "if user == active"

In all of them there are presented solutions mostly to alter functions from AuthController, however those functions are not there.

I am using latest version of Laravel (5.2) so my default mentioned file looks like: https://github.com/laravel/laravel/blob/master/app/Http/Controllers/Auth/AuthController.php

Now, how do I implement this functionality? I have tried copying public function postLogin() (as suggested in those other mentioned posts) into that AuthController file. Nothing changed.

I am clearly missing something here.

Please someone help!

Edit: The function that I have added is:

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

$credentials = $this->getCredentials($request);

// This section is the only change
if (Auth::validate($credentials)) {
    $user = Auth::getLastAttempted();
    if ($user->active) {
        Auth::login($user, $request->has('remember'));
        return redirect()->intended($this->redirectPath());
    } else {
        return redirect($this->loginPath()) // Change this to redirect elsewhere
            ->withInput($request->only('email', 'remember'))
            ->withErrors([
                'active' => 'You must be active to login.'
            ]);
    }
}

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

}
Community
  • 1
  • 1
Angelin Calu
  • 1,905
  • 8
  • 24
  • 44
  • If you are using `Route::auth()` to register the routes for Auth the method isn't `postLogin` its `login`, check your routes. – lagbox Jun 11 '16 at 23:10
  • Ok, I have renamed the function from `postLogin` to `login`. I had an exception raised about `Request` and I had to add `use Illuminate\Http\Request`. Now I get another exception: `Class 'App\Http\Controllers\Auth\Auth' not found` – Angelin Calu Jun 11 '16 at 23:17
  • That is a PHP namespacing issue. – lagbox Jun 11 '16 at 23:21
  • that is triggered on this line: `if (Auth::validate($credentials)) {` from the code written in the question. It's like I could not use the facade here. – Angelin Calu Jun 11 '16 at 23:24
  • 1
    It is a namespacing issue. You have to instruct PHP that class isn't in the current namespace. If you need a brief introduction to namespacing check out this article: [https://mattstauffer.co/blog/a-brief-introduction-to-php-namespacing](https://mattstauffer.co/blog/a-brief-introduction-to-php-namespacing) – lagbox Jun 11 '16 at 23:32

2 Answers2

1

Most functionality in AuthController is added using traits. Note this line in the beginning of the class:

use AuthenticatesAndRegistersUsers, ThrottlesLogins;

If you look at AuthenticatesAndRegistersUsers you can see that it does have a postLogin method.

As of why implementing this method doesn't work: I think you are missing the $request parameter in the method signature.

Add a larger code snippet to your question if this isn't the case.

EDIT: for future debugging: php artisan route:list gives you a list of which routes call which methods. This can give you a hint to which method to override.

user3389196
  • 161
  • 1
  • 6
  • So you are saying that I should instead update the function from [AuthenticatesAndRegistersUsers](https://github.com/laravel/framework/blob/5.0/src/Illuminate/Foundation/Auth/AuthenticatesAndRegistersUsers.php) ? – Angelin Calu Jun 11 '16 at 22:52
  • No, you should override it in `AuthController` (it should be possible). `AuthenticatesAndRegistersUsers` is located somewhere in your vendor directory which you shouldn't touch because changes are overriden by composer in no time. `AuthController` is a nice class in your project's Controllers directory which I think is intended for this kind of adaptions. Just copy the method signature (or maybe the whole method) from `AuthenticatesAndRegistersUsers`. – user3389196 Jun 11 '16 at 22:59
  • Exactly! I have updated my question with the function I have added. Besides that I have added `Use Request;` on the top of the `AuthController` file. Still didn't figured out why isn't working. – Angelin Calu Jun 11 '16 at 23:02
  • dont add `use Request` that is the facade, not the actual request class. – lagbox Jun 11 '16 at 23:08
  • With or without `Use Request`, it's still not working. And also no exceptions are raised. – Angelin Calu Jun 11 '16 at 23:11
  • Are you saying that you also don't have any exceptions without the `use Request;`? That seems weird. Anyway, instead of the facade, use `use Illuminate\Http\Request;` instead. – user3389196 Jun 11 '16 at 23:19
  • As @lagbox suggested, I had to change the function name from `postLogin` to `login`. Then I had the exception about Request, and I have added `use Illuminate\Http\Request;`. Now I have another exception about Auth. – Angelin Calu Jun 11 '16 at 23:22
0

So, for everyone facing the same problem on Laravel 5.2 with Authentication provided by php artisan make:auth.

First important thing is to understand that Route::auth(); points to login function and not postLogin(Thank you @lagbox!)

Then you will have to update AuthController:

Add on top of the file:

use Auth;
use Illuminate\Http\Request;

Add somewhere after use AuthenticatesAndRegistersUsers, ThrottlesLogins; :

/**
 * Where to redirect users if login is unsuccessufull.
 *
 * @var string
 */
protected $loginPath = '/login';`

And the updated login function:

public function login(Request $request)
{
$this->validate($request, [
    'email' => 'required|email', 'password' => 'required',
]);

$credentials = $this->getCredentials($request);

// This section is the only change
if (Auth::validate($credentials)) {
    $user = Auth::getLastAttempted();
    if ($user->active) {
        Auth::login($user, $request->has('remember'));
        return redirect()->intended($this->redirectPath());
    } else {
        return redirect($this->loginPath) // Change this to redirect elsewhere
            ->withInput($request->only('email', 'remember'))
            ->withErrors([
                'active' => 'You must be active to login.'
            ]);
    }
}

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

}

Then login.blade.php should be updated to show the new error @if ($errors->has('active'))

Thank you guys for help!

Angelin Calu
  • 1,905
  • 8
  • 24
  • 44