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

Login using OTP sent to email #3550

Open
pennersr opened this issue Dec 7, 2023 · 11 comments
Open

Login using OTP sent to email #3550

pennersr opened this issue Dec 7, 2023 · 11 comments

Comments

@pennersr
Copy link
Owner

pennersr commented Dec 7, 2023

See: #2061 (comment)

TBD:

  • Is this to be a setting that is globally (for all users) turned on/off, or, is this something that users would want to enable themselves?
  • Interaction with signup: if during signup we also send the OTP, sending an email verification link/code is no longer needed as the email is implicitly verified upon successful OTP login.
  • Requires ACCOUNT_EMAIL_REQUIRED = True -- should likely not be supported without.
  • If this is a global setting, it likely implies ACCOUNT_EMAIL_VERIFICATION = 'none' -- at least for login/signup. When adding a secondary email we still need to verify.
@josylad
Copy link

josylad commented Dec 7, 2023

Thanks for this. below is my use case and some of my own opinions.

Use case: I want to send OTP on user login, redirect the user to the OTP confirmation page, verify the OTP and then send them to their dashboard (or any page I desire).

Opinions:

  • Many people are not familiar with the workings of authenticator apps and some people do not want to install yet another app, so the idea of an Email OTP system comes into play. Email 2FA is very popular, especially in my region.
  • I believe it should be a global setting. We can activate it globally and require users to provide the OTP code from their email before they can log in.
  • Yes, it will require ACCOUNT_EMAIL_REQUIRED to be true.
  • The global setting could be something like EMAIL_OTP_VERIFICATION = True.

@pennersr
Copy link
Owner Author

pennersr commented Dec 7, 2023

I made a little PoC for a feature like this, I've pushed that here:

https://github.com/pennersr/django-allauth/tree/feat-otp-login

It's functional but definitely not finished. Would appreciate it if you could give it a test spin to see if this matches your use case.

MFA_EMAIL_OTP = True.

@pennersr
Copy link
Owner Author

pennersr commented Dec 7, 2023

FWIW -- it's reusing the regular mfa flow:

image

@josylad
Copy link

josylad commented Dec 7, 2023

I made a little PoC for a feature like this, I've pushed that here:

https://github.com/pennersr/django-allauth/tree/feat-otp-login

It's functional but definitely not finished. Would appreciate it if you could give it a test spin to see if this matches your use case.

MFA_EMAIL_OTP = True.

Thank you for this. I will test it and share feedback with you.

@josylad
Copy link

josylad commented Dec 7, 2023

Hi,
I just tested it and this is exactly what I need!

image

image

I got the OTP, entered it and the user was sent to the dashboard!

Thank you.

@josylad
Copy link

josylad commented Dec 8, 2023

Hi @pennersr
I hope this feature will make it to the next update. 😉️

@apagano-vue
Copy link

apagano-vue commented Mar 28, 2024

@pennersr: We would also be really interested in having this feature directly available in django-allauth. We have already adapted your PoC (thank you so much for that!) to integrate this feature into our app without having to maintain a fork of django-allauth. I'd be happy to share the diff if you are interested. A few changes that we made FYI:

  1. the factor can be enabled on a per-user basis (for now we just added a boolean field to our user model that is checked instead of app_settings.EMAIL_OTP).
  2. email code is checked first in the stage and form. This makes sure that enabling the email code factor takes precedence over any eventual totp Authenticator already created for a user (so that a user who already setup the "regular" totp factor in the past can still enable email code authentication)

@simkimsia
Copy link
Sponsor Contributor

I'm sorry but how do I test in a production site?

Am using 0.61.1 for Django 4.2

@josylad
Copy link

josylad commented Apr 1, 2024

I'm sorry but how do I test in a production site?

Am using 0.61.1 for Django 4.2

Do this:
pip install django-allauth @ git+https://github.com/pennersr/django-allauth.git@1eaf7a3ae8bd210a9f6cba496ef3c23807d6f15d

This will install the branch with this feature.

@pennersr
Copy link
Owner Author

pennersr commented Apr 5, 2024

I would like to see this implemented in allauth. Though, I am still a bit add odds on the exact requirements. I initially envisioned this as a feature that would be turned on/off globally via the settings. But I see that @apagano-vue is using this as something that is under control of the user. @apagano-vue vue, can you please sketch how this works for your users? Also interested in what the possible UI looks like. For example, can they enable/disable this just like e.g. TOTP authentication?

Any input, and any good examples of how other sites are implementing this is welcome.

@Okan0
Copy link

Okan0 commented May 3, 2024

Currently, I am migrating from a custom implementation to Allauth. During this process, I discovered that email-based two-factor authentication (2FA) is not possible. Therefore, I would also like to see this feature implemented.

The option for email-based 2FA should only be available if an email address is known AND the current primary email address is verified. After activation, changing the primary email address should only be possible if the "new" email address is also verified.

To control the activation, I see two possible approaches:

  1. Only one option can be activated at a time, and after successfully activating another option, the previous one will be deactivated. However, I believe the recovery codes should be an integral part of the Authenticator App, considered as a subpoint of the "only one option" within the app.
  2. Alternatively, multiple options can be activated. In this case, it would be possible to let the user choose the "primary" method (Again, I would consider recovery codes only as part of the Authenticator App and in the case of this method, continue to verify recovery codes as before). If the user has activated multiple options, they would need to enter their primary method first during the second login step, but they would have the option to switch to an alternative method. I would actually model this process quite similarly to MS Office.

In my view, this would lead to the following extension:

  • New Setting MFA_MULTIPLE_CHOICES, alternatively MFA_MAX_MODES_COUNT
  • add default "email" to existing settingMFA_SUPPORTED_TYPES and add to docs
  • Extension of the Authenticator model to include the "primary"
  • Extension of the view similar to "reauthentication" to include "get_alternative_methods"
  • New views for individual 2FA methods OR Post or similar for the internal method switch. Switching to email should trigger a send
  • New view for "Resend Code"
  • Implement cooldowns/throttling for code resend
  • Extension of MFAAdapter for validation (e.g., with signature def validate_code(code, types=None) -> Optional[Authenticaor])
  • Storing the "Email Code" in the session
  • Storing the "expected" 2FA types in the session in case it's not "controlled" view based

UI wise it could look something like this for Option 1:
image
image

And this for Option 2 (MS):
Screenshot 2024-05-03 at 11 44 27

or something like this
image
image

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

No branches or pull requests

5 participants