-
Notifications
You must be signed in to change notification settings - Fork 11.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resolve TokenRepositoryInterface from Container rather than new DatabaseTokenRepository(...) #15071
Comments
Funny, I just ended up in the exact same place looking for a way to do username based password resets. The column |
Ended up there initially because need to change the hash length (nothing On 2 Sep 2016 20:22, "Dave" notifications@github.com wrote:
|
Please feel free to open a PR with the suggested changes, I think you have a point here. Closing this since it's not actually a bug :) please ping me if you think otherwise. |
This is probably irrelevant once 5.5 is released because of #17499 but I wanted to modify the Reset Password functionality so it would not generate a new token each time a user clicks the link. If a user is impatient and clicks the Reset Password more than once, then the first email they receive is now invalid because the token was replaced. Instead, I just want the 2nd email to contain the same token as the first email did. I subclassed Here's what I had to do for this to work:
//Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
App\Auth\Passwords\MLPasswordResetServiceProvider::class,
class MLPasswordResetServiceProvider extends PasswordResetServiceProvider
{
/**
* Register the password broker instance.
*
* @return void
*/
protected function registerPasswordBroker()
{
$this->app->singleton('auth.password', function ($app) {
return new MLPasswordBrokerManager($app);
});
$this->app->bind('auth.password.broker', function ($app) {
return $app->make('auth.password')->broker();
});
}
}
class MLPasswordBrokerManager extends PasswordBrokerManager
{
/**
* Create a token repository instance based on the given configuration.
*
* @param array $config
* @return \Illuminate\Auth\Passwords\TokenRepositoryInterface
*/
protected function createTokenRepository(array $config)
{
$key = $this->app['config']['app.key'];
if (Str::startsWith($key, 'base64:')) {
$key = base64_decode(substr($key, 7));
}
$connection = isset($config['connection']) ? $config['connection'] : null;
return new MLDatabaseTokenRepository(
$this->app['db']->connection($connection),
$this->app['hash'],
$config['table'],
$key,
$config['expire']
);
}
}
class MLDatabaseTokenRepository extends DatabaseTokenRepository
{
/**
* Create a new token record.
*
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
* @return string
*/
public function create(CanResetPasswordContract $user)
{
$email = $user->getEmailForPasswordReset();
// If the user already has a valid token, send it instead of creating a new one.
// This will prevent the impatient user from being frustrated if they clicked
// Reset Password more than once.
$record = (array)$this->getTable()
->where('email', $email)
->first();
$exists = $record && !$this->tokenExpired($record['created_at']);
if ($exists) {
return $record['token'];
}
$this->deleteExisting($user);
// We will create a new, random token for the user so that we can e-mail them
// a safe link to the password reset form. Then we will insert a record in
// the database so that we can verify the token within the actual reset.
$token = $this->createNewToken();
$this->getTable()->insert($this->getPayload($email, $token));
return $token;
}
} |
Hi, |
I've been looking over a simple way of making a couple of minor amends to the Auth\Passwords in a project and have spotted that
PasswordBrokerManager
createTokenRepository()
news a DatabaseTokenRepository() instance rather than resolving the\Illuminate\Auth\Passwords\TokenRepositoryInterface
(which would be expected from the docblock).Likewise the
PasswordBrokerManager
resolve()
method new's an\Illuminate\Contracts\Auth\PasswordBroker
instance (which is is in the IOC asauth.password
).I was looking at overriding a couple of methods and rebinding a new implementation of TokenRepositoryInterface before realising that this wasn't always used (only when type hinted in the construct).
What I'm asking is there a specific reason we are newing instances of contract implemenations which if were resolved, could be overridden? And if there is no reason, would a PR to change this behaviour be accepted.
I'd rather not create all the boilerplate of a new PasswordResetServiceProvider for what would be a couple of methods to override.
The text was updated successfully, but these errors were encountered: