Hey,
I just recently upgraded my Laravel 5.1 installation to the latest version of Laravel 5.2.
I followed the upgrade guide and everything works, except for the password reset form. The form shows but as soon as I submit it, I get the above error.
My custom user provider works just fine with a fresh installation of Laravel.
I was in the IRC for almost 1.5hrs and even digging that long did not help so I suspect there might be something the upgrade notes have not covered.
Looks like you didn't copy over the new configuration files from the laravel/laravel repo.
Like I said: regular authentication works just fine using my custom auth provider, only password resets don't.
Somehow my custom user provider get's called twice and the second time the $customProviderCreators array is empty...
Could you attach your config/auth.php ?
Sure, but I am a 100% sure it's not because of the config:
(Like I said, and I said that a lot in the IRC as well: it runs perfectly fine with a clean installation of Laravel 5.2)
Have you cleared the config cache?
If I wouldn't have cleared my config cache, the user provider wouldn't work at all: Like I said (repeating myself the fourth time) it works everywhere except on the password reset page.
I did clear all caches.
@dhardtke Any solution? I'm having the same issue, and this is driving me insane.
Nope, no solution. The only thing I can think of is that the upgrade guide has not covered all things necessary to get the custom auth provider working.
How do you have this working on a fresh install even? $customProviderCreators never gets initiated with the custom providers for PasswordBrokerManager...there is not even a way to add it. I've added the provider() method from AuthManager to the CreatesUserProviders trait, and that's a solution, but it kind of sucks.
It's possible I'm missing something here as my brain isn't really working anymore.
[...] there is not even a way to add it [...]
that's not true. Try this:
auth()->provider("nameOfYourProvider", function ($app, array $config) {
return new MyUserProvider(...);
});
It's possible I'm missing something here as my brain isn't really working anymore.
wat
That's for AuthManager. This is why everything else concerning auth works okay. Password reset uses PasswordBrokerManager, and does not have the ability to add a provider (which is why $customProviderCreators is empty "the second time").
So by moving the provider() method in AuthManager to the CreatesUserProviders trait, I can now do
Password::provider("nameOfYourProvider", function ($app, array $config) {
return new MyUserProvider(...);
});
and that works, but it's not ideal to me.
aah. so you basically found the problem - nice!
Update:
So to sum up the problem: The AuthManager uses the CreatesUserProviders trait and provides a provider method to fill the $customProviderCreators array. The PasswordBrokerManager on the other hand, which is being used by the ResetsPassword trait, does use the CreatesUserProviders trait as well and therefore has its own $customProviderCreators array, independent from the AuthManager ones.
Basically we need to find a way to "unify" them, or at least fill the $customProviderCreators array of the PasswordBrokerManager too.
So this is indeed a bug in Laravel (imo).
Another Update:
I did not set up a database and got an Exception on my fresh Laravel install and thought that the User Provider caused this, but the Custom User Provider is not working there either... after setting up the DB correctly I also get the same error.
I am a 100% sure this is a bug in Laravel 5.2.
What I did was adding the following code to createUserProvider function inside CreatesUserProviders.php.
case 'custom':
return new CustomUserProvider();
That works fine for me.
Bug solved?
@crynobone I read:
That works fine for me.
This can only be solved by binding auth.user.provider to the IoC and then both AuthManager and PasswordBrokerManager can use it.
I'm not sure if converting the $customProviderCreators to static can solve it.
@crynobone can you give an example of how you bind auth.user.provider to the IoC?
@whoacowboy that was just a suggestion on how we could solve the problem. The code is not available yet.
@GrahamCampbell @lucasctd I too am having this issue. Adding another case in CreatesUserProviders.php worked for me as well.
Like @dhardtke it looks like createUserProvider is being called twice.
This gives me the name of my driver twice when I test it.
public function createUserProvider($provider)
{
$config = $this->app['config']['auth.providers.'.$provider];
var_dump($config['driver']);
if (isset($this->customProviderCreators[$config['driver']])) {
return call_user_func(
$this->customProviderCreators[$config['driver']], $this->app, $config
);
}
switch ($config['driver']) {
case 'database':
return $this->createDatabaseProvider($config);
case 'eloquent':
return $this->createEloquentProvider($config);
default:
throw new InvalidArgumentException("Authentication user provider [{$config['driver']}] is not defined.");
}
}
+1 on bug
There are basically two case for driver database and eloquent so if me use custom name for driver we gonna get error is it correct?
Most helpful comment
that's not true. Try this:
wat