Skip to content
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

[11.x] allow for multiple providers in password reset table #53169

Closed

Conversation

browner12
Copy link
Contributor

I am currently building an application with multiple authentication "providers" and "guards" for the first time.

When setting up my password resets, it seem like the intent is to have multiple tables, one for each "provider". However, it seems like we could easily handle multiple providers in a single table and ensure no collisions by adding a provider column.

In order to accomplish this in a non-breaking way (due to the required migration), I use an optional boolean multiple key in the auth.passwords.{name} config. Setting this to true will indicate to the DatabaseTokenRepository a provider field has been added to the password_reset_tokens table. When either selecting or inserting rows into this table, the DatabaseTokenRepository will now conditionally check the provider column as well.

If the multiple key is omitted or set to false, the DatabaseTokenRepository will behave as before, and only check against the email address.


This would be an example auth config:

'passwords' => [
    'customers' => [
        'provider' => 'customers',
        'table'    => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'),
        'expire'   => 60,
        'throttle' => 60,
        'multiple' => true,
    ],
    'users'     => [
        'provider' => 'users',
        'table'    => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'),
        'expire'   => 60,
        'throttle' => 60,
        'multiple' => true,
    ],
],

This would be the new migration:

Schema::create('password_reset_tokens', function (Blueprint $table) {
    $table->string('provider');
    $table->string('email');
    $table->string('token');
    $table->timestamp('created_at')->nullable();
    $table->primary(['provider', 'email']);
});

Another option I played around with for checking table schema compatibility is querying the table schema when constructing the DatabaseTokenRepository. this works and is more automatic, but it obviously costs us an extra query. if that tradeoff is okay, I could switch back to it.

when using multiple authentication providers in an application, allow both providers to use the same password reset table.

if a `multiple` key is added in the `auth.passwords.{key}` config, this will indicate a `provider` field has been added to the `password_reset_tokens` table. when either selecting or inserting rows into this table, the `DatabaseTokenRepository` will conditionally check the `provider` column as well.
@taylorotwell
Copy link
Member

Hmm, don't love having to have the multiple flag. Think I'll table this one for now. 😬

@browner12
Copy link
Contributor Author

@taylorotwell are you open to another way to flag this, maybe via the schema check? It would be ideal if this was just the default behavior, but obviously we can't do that due to BC. would you be open to this change as the default in 12.x?

if you're still going to table this right now, what is currently the official way to handle multi-auth password resets? a separate table for each?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants