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

Open providers to more complex passwordless use cases #414

Closed
armandabric opened this issue Jul 9, 2020 · 9 comments
Closed

Open providers to more complex passwordless use cases #414

armandabric opened this issue Jul 9, 2020 · 9 comments
Labels
enhancement New feature or request

Comments

@armandabric
Copy link

Summary of proposed feature

Currently the project contain only one implementation of passwordless authentication: a magic link by email. This proposal aim to find a way to add more passwordless authentication types.

Purpose of proposed feature

The actual Email provider is not enough for more passwordless use cases. The current API implementation is too email specific to allow to implement other providers that fit other passwordless processes.

For example:

  • When the signin("email", { email: "foo@bar.fr" }) function is called, the user is redirected to dedicated page. This an ok behaviour for email where the user will have to click in the email and start a new navigation session. But in some other case it's not always the good think to do. For example for a SMS provider it could be better to show an input for the verification code

https://github.com/iaincollins/next-auth/blob/5db05e1031d07f3651e6e58f1fa046acb1018135/src/client/index.js#L136-L151

  • There is no way to manually verify the user: it miss a function like the signin() and signout() one. This function could allow to do a SMS verification for example: verifyUser("sms", { code: "1234" })

  • The email provider does not generate the token or the destination url: it's should it responsability

https://github.com/iaincollins/next-auth/blob/5db05e1031d07f3651e6e58f1fa046acb1018135/src/providers/email.js#L25

Detail about proposed feature

  • Create a dedicated "passwordless" provider type

    • Rename the "email" provider type to "passwordless"
    • Rename the "Email" provider to "MagicLinkByEmail" and make it a "passwordless" provider type
  • Add method on the "passwordless" provider type to avoid specific code in the core API:

    • Add a generateVerificationContext(...). Called before the actual sendVerificationRequest, it allow to generate any data that could be used to validate an user: token/url for an email provider, code for an sms provider
    • Add a notifyVerificationRequestWasSend(...). Called after sendVerificationRequest, this method could be use to implement the redirection to the email page in case of Email provider
    • Add a validateUser method to validate the user token/code. It will by called during the verify process
  • Add a verifyUser(providerName, args) function to the client. It would trigger the verify process on the passwordless provider, and trigger an error on a oauth provider

In less precise way, a lot of change is necessary to have two clear paths in the authentication process: the oauth one, an the passwordless one.

Potential problems

  • OAuth vs passwordless flow: keep both flow simple and close but without merging to much code
  • Complexify passwordless provider creation

Describe any alternatives you've considered

Forking the library to make one dedicated to passwordless authentication

Additional context

I have looked at the work done in #409. It's a good start and shows that a lot of logic that allow the actual email provider to work is not in the provider itseft but split in different location.

Some on the split here is inspired by the Cognito custom flow. Maybe the proposed flow need to be changed to more next-auth specific.


I know that this proposal contains a lot of changes. If the general idea is accepted, I will be more than happy to help to implement them.

Thanks for reading me! 👌

@armandabric armandabric added the enhancement New feature or request label Jul 9, 2020
@tmayr
Copy link
Contributor

tmayr commented Jul 9, 2020

Nice summary!

I agree with all of your points, I would only add to the discussion:

Right now the Authentication "token" for email is the CSRF token, with this proposal we would change it to a PIN code, wondering if theres any security implications in sending:

http://localhost/api/auth/signin?email=foo@bar.com&csrf=<csrf generated token>
vs
http://localhost/api/auth/signin?email=foo@bar.com&code=<short code>

My guess would be that, other than people theoretically guessing your email and code being more probable than the csrf token, but in reality it shouldn't be an issue.

And regarding the page for the email/code, I think changing how the verification page works should be enough, you can prefill the code (csrf or short) if it's in the url or just show an input to enter your code if it's not present would satisify the SMS approach, that + having a way to do your own thing with the code (as my PoC attempts to do), should work wonders for both issues I believe

@iaincollins
Copy link
Member

Thanks for the submission, it ties in nicely with what @tmayr has been looking at in #409 that you've linked to.

Essentially this is the plan for the email provider, that's why methods and data structures have generic names like createVerificationRequest and sendVerificationRequest and use column names like identifier instead of email.

It's also why properties like maxAge are configurable at the provider level - as it's likely you'd want to use a shorter expiry time with simpler verification codes sent over SMS.

It's likely something we will introduce in non-breaking way in a future update. There is still some detail to work through though. Your offer of help to add this is much appreciated and might take you up on that when I come back to this after v3 is released. :-)

Right now the Authentication "token" for email is the CSRF token, with this proposal we would change it to a PIN code, wondering if theres any security implications in sending:

Just to pick up on that, the current token is actually a unique key generated with crypto (and not the CSRF token). The key is compared a salted hash of that key stored in the database, so that even if the contents database is compromised in a data dump it cannot be exploited to sign in as a user.

We would want to do something similar if storing shorter keys (e.g. codes sent over SMS) but we should consider more flexibility to also support varying using 2FA tokens or hardware devices.

You can currently do this using a credentials provider, but there are limitations (e.g. only works JSON Web Tokens and users are not persisted in the database).

The reason this feature is not more generic already is that I'd like to sure we are doing this in the best way to help keep people safe and provide a clear way of them using a feature like short codes in a secure way as possible.

We MIGHT also want to look at cross device sign in - e.g. when someone tries to sign in on the desktop, send a link to a phone over email or text, have them open it on a phone, but them log them in on the phone and/or desktop they signed in from. I'm not sure if that is something that would be fully in scope, but I think it's worth considering what would be required and seeing if it's a thing we could do - or at least lay the ground work for - at the same time.

@armandabric
Copy link
Author

I'm glad that we are on the same page 👌

I will be available in august to start to work on it. I suppose that the the v3 will be there, or really close to be release, so we could start to work on the passwordless flow

We would want to do something similar if storing shorter keys (e.g. codes sent over SMS) but we should consider more flexibility to also support varying using 2FA tokens or hardware devices.

I agree with that point, there is too many use case to be able to covert them all. We have to find a way to store the "validation codes" in a generic way

We MIGHT also want to look at cross device sign in - e.g. when someone tries to sign in on the desktop, send a link to a phone over email or text, have them open it on a phone, but them log them in on the phone and/or desktop they signed in from.

That is something I'm also looking for. It's a nice next feature to work on after working on the passwordless core flow

@stale
Copy link

stale bot commented Dec 5, 2020

Hi there! It looks like this issue hasn't had any activity for a while. It will be closed if no further activity occurs. If you think your issue is still relevant, feel free to comment on it to keep ot open. Thanks!

@stale stale bot added the wontfix This will not be worked on label Dec 5, 2020
@balazsorban44 balazsorban44 added stale Did not receive any activity for 60 days and removed wontfix This will not be worked on labels Dec 5, 2020
@stale
Copy link

stale bot commented Dec 12, 2020

Hi there! It looks like this issue hasn't had any activity for a while. To keep things tidy, I am going to close this issue for now. If you think your issue is still relevant, just leave a comment and I will reopen it. (Read more at #912) Thanks!

@stale stale bot closed this as completed Dec 12, 2020
@durdenx
Copy link

durdenx commented Dec 15, 2020

Is it possible to use a verification code instead of a magic link for passwordless auth ? If users use their phone to open the magic link, they won't be logged in on PC.

@balazsorban44 balazsorban44 reopened this Dec 15, 2020
@balazsorban44 balazsorban44 removed the stale Did not receive any activity for 60 days label Dec 15, 2020
@berndartmueller
Copy link

I would also really appreciate this feature! Is there any news regarding the progress on the implementation?

@balazsorban44
Copy link
Member

balazsorban44 commented Mar 7, 2021

This is a very good idea!
To all of you interested in this, I recently opened an RFC in discussions about this! #1465 Feel free to comment on it! I am going to close this issue and kindly ask any future visitors to go to the discussion instead

@narciero
Copy link
Contributor

for anyone looking for an interim solution, I wrote a brief blog post on how I built a passwordless integration with Magic using the Credentials provider...it's worked pretty well so far

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

No branches or pull requests

7 participants