3

I've successfully implemented Laravel's Auth for Registration, Login and Logout. However, I'm having quite a bit of difficulty resolving the following error trying to implement the password reset functionality.

Error: User must implement CanResetPassword interface.

I believe my User class is configured properly:

use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;

class User extends Model implements AuthenticatableContract, 
                                    CanResetPasswordContract {
    use Authenticatable, CanResetPassword;
    ...
}

I'm not using Eloquent, so I have the following in config/auth.php:

'driver' => 'database'

Does anyone have any idea why I'm getting the "User must implement CanResetPassword interface" error?

Thanks much!

EDIT: Adding Stack Trace:

UnexpectedValueException in PasswordBroker.php line 237: 
User must implement CanResetPassword interface .

in PasswordBroker.php line 237
at PasswordBroker->getUser( array('email' => '[email protected]')) in PasswordBroker.php line 81
at PasswordBroker->sendResetLink (array('email' => '[email protected]'), object(Closure)) in Facade .php line 217
at Facade::__callStatic('sendResetLink' , array(array('email' => '[email protected]'), object(Closure))) in ResetsPasswords.php line 35
at Password::sendResetLink(array ('email' => '[email protected]'), object(Closure)) in ResetsPasswords .php line 35
at PasswordController->postEmail (object(Request))
at call_user_func_array(array(object(PasswordController), 'postEmail'), array( object(Request))) in Controller.php line 256
at Controller->callAction('postEmail', array(object(Request))) in ControllerDispatcher .php line 164
at ControllerDispatcher->call (object(PasswordController), object(Route), 'postEmail') in ControllerDispatcher .php line 112
at ControllerDispatcher->Illuminate \Routing\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 139
at Pipeline->Illuminate\Pipeline\{closure }(object(Request)) in RedirectIfAuthenticated.php line 41
at RedirectIfAuthenticated->handle(object(Request), object(Closure))
at call_user_func_array(array(object(RedirectIfAuthenticated), 'handle'), array (object(Request), object(Closure))) in Pipeline.php line 124
at Pipeline->Illuminate\Pipeline\{closure }(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 103
at Pipeline->then(object(Closure)) in ControllerDispatcher.php line 114
at ControllerDispatcher->callWithinStack (object(PasswordController), object(Route), object(Request), 'postEmail') in ControllerDispatcher.php line 69
at ControllerDispatcher->dispatch (object(Route), object(Request), 'App\Http\Controllers\Auth\PasswordController', 'postEmail') in Route.php line 203
at Route->runWithCustomDispatcher(object (Request)) in Route.php line 134
at Route->run(object(Request)) in Router.php line 704
at Router->Illuminate\Routing\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 139
at Pipeline->Illuminate\Pipeline\{closure }(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 103
at Pipeline->then(object(Closure)) in Router.php line 706
at Router->runRouteWithinStack(object< /em>(Route), object(Request)) in Router.php line 671
at Router->dispatchToRoute(object (Request)) in Router.php line 631
at Router->dispatch(object(Request)) in Kernel.php line 236
at Kernel->Illuminate\Foundation\Http \{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 139
at Pipeline->Illuminate\Pipeline\{closure }(object(Request)) in Debugbar.php line 49
at Debugbar->handle(object (Request), object(Closure ))
at call_user_func_array(array(object(Debugbar), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 124
at Pipeline->Illuminate\Pipeline\{closure }(object(Request)) in VerifyCsrfToken.php line 50
at VerifyCsrfToken->handle(object(Request), object(Closure))
at call_user_func_array(array(object(VerifyCsrfToken), 'handle'), array(object (Request), object(Closure ))) in Pipeline .php line 124
at Pipeline->Illuminate\Pipeline\{closure }(object(Request)) in ShareErrorsFromSession .php line 49
at ShareErrorsFromSession ->handle(object(Request), object(Closure))
at call_user_func_array(array(object(ShareErrorsFromSession), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 124
at Pipeline->Illuminate\Pipeline\{closure }(object(Request)) in StartSession.php line 62< /a>
at StartSession->handle(object(Request), object(Closure))
at call_user_func_array(array(object(StartSession), 'handle'), array(object(Request), object(Closure))) in Pipeline .php line 124
at Pipeline->Illuminate\Pipeline\{closure }(object(Request)) in AddQueuedCookiesToResponse .php line 37
at AddQueuedCookiesToResponse ->handle(object(Request), object(Closure))
at call_user_func_array(array(object(AddQueuedCookiesToResponse), 'handle'), array (object(Request), object(Closure))) in Pipeline.php line 124
at Pipeline->Illuminate\Pipeline\{closure }(object(Request)) in EncryptCookies.php line 59
at EncryptCookies->handle (object(Request), object(Closure))
at call_user_func_array(array(object(EncryptCookies), 'handle'), array(object(Request), object(Closure))) in Pipeline .php line 124
at Pipeline->Illuminate\Pipeline\{closure }(object(Request)) in CheckForMaintenanceMode .php line 42
at CheckForMaintenanceMode ->handle(object(Request), object(Closure))
at call_user_func_array(array(object(CheckForMaintenanceMode), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 124
at Pipeline->Illuminate\Pipeline\{closure }(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 103
at Pipeline->then(object(Closure)) in Kernel.php line 122
at Kernel->sendRequestThroughRouter (object(Request)) in Kernel.php line 87
at Kernel->handle(object( Request)) in index.php line 54
5
  • Are you implementing all of the methods the interface? There's only one, getEmailForPasswordReset(), do you have that implemented in your User class? github.com/laravel/framework/blob/5.1/src/Illuminate/Contracts/… Commented Nov 10, 2015 at 1:41
  • 1
    No, I haven't implemented that method, or any in the Authenticatable interface. I believe I'm using the default methods in the traits. Commented Nov 10, 2015 at 1:53
  • Oh, duh, I missed that you had both the traits and the interfaces. What are you trying to do that fails? Post the full stack trace Commented Nov 10, 2015 at 2:11
  • Stack Trace added as edit in OP above. Thanks! Commented Nov 10, 2015 at 11:32
  • Oh, forgot to add: I'm clicking the "Send Password Reset" link on the "Reset Password" page. Commented Nov 10, 2015 at 11:41

3 Answers 3

3

I faced this problem in laravel 5.2, and I found a solution like as:

<?php
    namespace App;
    use Eloquent;
    // use Illuminate\Foundation\Auth\User as Authenticatable;
    use Illuminate\Contracts\Auth\Authenticatable;
    use Illuminate\Auth\Authenticatable as AuthenticableTrait;
    use Illuminate\Auth\Passwords\CanResetPassword;
    use Illuminate\Contracts\Auth\CanResetPassword as
               CanResetPasswordContract;

    class User extends Eloquent implements
             Authenticatable,CanResetPasswordContract        

     {
         use AuthenticableTrait,CanResetPassword;
         .......
         .......
     }  
Sign up to request clarification or add additional context in comments.

2 Comments

I had the same issue and this solution worked for me, I was missing use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract; on my class bellow after AuthenticatableContract class User extends Eloquent implements AuthenticatableContract,CanResetPasswordContract
Simply implementing CanResetPassword worked perfect for me
2

Follow your stack trace.

PasswordBroker.php line 237

https://github.com/laravel/framework/blob/5.1/src/Illuminate/Auth/Passwords/PasswordBroker.php#L237

Fails because DatabaseUserProvider's retrieveByCredentials returns a GenericUser object, not your User class object.

https://github.com/laravel/framework/blob/5.1/src/Illuminate/Auth/DatabaseUserProvider.php#L99

What this means, basically, is that the password reminder functionality that Laravel comes with is only supported by the eloquent auth driver. You can't use it with the database driver. Your options are

  1. switch to Eloquent
  2. build out password resets by yourself, or
  3. add your own custom auth driver

Inside of a service provider (AppServiceProvider, or create a new one):

Auth::extend('custom', function($app) {
    return new CustomUserProvider($app['database.connection']);
});

It might be as simple as extending the database user provider and overriding getGenericUser to use your class instead.

class CustomUserProvider extends \Illuminate\Auth\DatabaseUserProvider
{
    protected function getGenericUser($user) {
        if ($user !== null) {
            return new \App\User((array) $user);
        }
    }
}

6 Comments

I did see the "PasswordBroker.php line 237" in the Trace and looked at that function. From what I've read, I thought that the Auth Scaffolding worked with 'database.' I'll try creating the Custom Auth driver you mentioned above, as it's took late to switch to Eloquent. Thanks, and will let you know how it goes!
Quick Clarification... On the Custom Auth Driver page, it says: "If you are not using a traditional relational database to store your users, you will need to extend Laravel with your own authentication driver." I'm using MySQL, and it is working fine with Registration and Login. I would think Password Reset would work with MySQL as well. No?
@RobertFrenette everything Auth related works except password reminder stuff. If you look at the GenericUser class you'll see that it implements Authenticatable but not CanResetPassword. Kind of annoying since CanResetPassword just has the one "get email" method
@RobertFrenette the "not using a traditional relational database" is just one example of why you'd need to extend it. This is another example
andrewtweber - wanted to get back to you. I wasn't having any luck with a custom auth driver, so I decided to roll-my-own Password Reset functionality. Thanks for weighing in on this.
|
0

The below should work in Any Model You Created

    namespace App;

    use Illuminate\Database\Eloquent\Model;
    use Illuminate\Contracts\Auth\Authenticatable;
    use Illuminate\Auth\Authenticatable as AuthenticableTrait;
    use Illuminate\Contracts\Validation\Validator;
    use Illuminate\Foundation\Validation\ValidatesRequests;
    use Illuminate\Auth\Passwords\CanResetPassword;
    use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
    use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;



class customer extends Model implements AuthenticatableContract,CanResetPasswordContract
{
        //protected $primaryKey = 'customerId';
        use AuthenticableTrait,CanResetPassword;
        use ValidatesRequests;
    protected $fillable=['name','email','password','country','favorite','gender','image'];
        protected $hidden = [
        'password', 'remember_token',
    ];
}

hope it helps

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.