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

chadhortonwowza's avatar

Issue with Auth - receiving undefined method

Hello,

I have set up passport and auth following the instructions on laravel. When I try to register, login, etc. and submit the form, I get something similar to this error (this one after submitting a login form):

FatalErrorException in AuthenticatesUsers.php line 75: Call to undefined method Illuminate\Auth\RequestGuard::attempt() in AuthenticatesUsers.php line 75

0 likes
9 replies
chadhortonwowza's avatar

Here you go:

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option controls the default authentication "guard" and password
    | reset options for your application. You may change these defaults
    | as required, but they're a perfect start for most applications.
    |
    */

    'defaults' => [
        'guard' => 'api',
        'passwords' => 'users',
    ],

    /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | here which uses session storage and the Eloquent user provider.
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | Supported: "session", "token"
    |
    */

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'passport',
            'provider' => 'users',
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | User Providers
    |--------------------------------------------------------------------------
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | If you have multiple user tables or models you may configure multiple
    | sources which represent each model / table. These sources may then
    | be assigned to any extra authentication guards you have defined.
    |
    | Supported: "database", "eloquent"
    |
    */

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],

        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Resetting Passwords
    |--------------------------------------------------------------------------
    |
    | You may specify multiple password reset configurations if you have more
    | than one user table or model in the application and you want to have
    | separate password reset settings based on the specific user types.
    |
    | The expire time is the number of minutes that the reset token should be
    | considered valid. This security feature keeps tokens short-lived so
    | they have less time to be guessed. You may change this as needed.
    |
    */

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60,
        ],
    ],

];
davielee's avatar

Ok, so you see where you put the default guard as api...

'defaults' => [
    'guard' => 'api',
    'passwords' => 'user',
],

Unless your app is specifically an API, you might not want to do that. When you do that and use the baked-in AuthenticatesUsers trait, it doesn't explicitly use the web guard. It just uses the default.

protected function attemptLogin(Request $request)
{
    return $this->guard()->attempt(
        $this->credentials($request), $request->has('remember')
    );
}

The guard you have selected doesn't contain an attempt method. The guard getting fired in your case by the way is Laravel\Passport\Guards\TokenGuard. So to get around this, I would suggest you turn the default guard back to web, then in your api.php routes, you can either group or add the auth middleware to your routes like the following.

Route::group([
    'middleware' => 'auth:api',
], function () {
    // ...
});

// or ...

Route::get('/users/{user}', 'UserController@show')->middleware('auth:api');
4 likes
chadhortonwowza's avatar

Ah I see! This fixed it! Thank you.

This leads me to another question, then. Is there an existing way of managing users (register, password reset) via artisan or some other method? If I knew how the passwords hashed, I could write something myself, but I can't figure out how it's done.

davielee's avatar

@chadhortonwowza Glad that worked. As for your other question, I'm not sure I understand what you mean. What sorts of existing functionality are you asking about?

chadhortonwowza's avatar

in order to use passport 'password' grant type, I have to have users (that are stored in the users table). I want to be able to manage those users. I would prefer if I could write my own artisan command but in order to do so I need to know how the passwords are hashed that get stored in the database. I can't quite figure out how it's done.

davielee's avatar

Oh I see. Ok well by default with the auth:make registration and the accepted way of hashing your passwords is using one of the following methods.

// This is used in the RegisterController for the auth:make setup.
bcrypt($password);
// This is what the bcrypt() global helper function does under the hood.
Hash::make($password)

Those methods, which do the exact same thing work like this.

Illuminate\Hashing\BcryptHasher

public function make($value, array $options = [])
{
    $cost = isset($options['rounds']) ? $options['rounds'] : $this->rounds;

    $hash = password_hash($value, PASSWORD_BCRYPT, ['cost' => $cost]);

    if ($hash === false) {
        throw new RuntimeException('Bcrypt hashing not supported.');
    }

    return $hash;
}

It first determines the amount of rounds to use when hashing, which is called the cost. The hash is then generated using PHP's native password_hash method. If it comes back as false that means that your environment doesn't support Laravel's default BcryptHasher class, otherwise you get the hashed password back.

You could of course make your own...but that is seriously not recommended.

1 like
chadhortonwowza's avatar

Perfect. That works like a charm. Thank you. Very much appreciated.

1 like
warren32's avatar

Also, don't forget that you can use Auth::guard('web')->attempt() to manually set the guard instead if you are using manual authentication methods described in the laravel docs. This could be beneficial if you do have an API and have some sort of client side login on a single page app using Vuejs.

Please or to participate in this conversation.