I’m wondering if there exists a pattern or example to extend a live_view application which uses authentication generated by mix phx.gen.auth with a MFA mechanism, e.g. incorporating NimbleTOTP ?
I read a little bit on MFA in the live view socket documentation, but doesn’t help me a lot, any suggestions to this kind of problem ?
The blog here describes what you need to add to implement TOTP:
I would suggest that you challenge and verify the TOTP secret during registration process to ensure the user has added it correctly to their the authentication app/manager.
Ensure in your context that your changeset for a new user registration generates a random TOTP secret for the user.
Have your liveview registration form generate and render the TOTP barcode and instructions and also provide a TOTP challenge field.
On submit of the registration you will now have the users email, password, password confirmation and challenge so you just validate the changeset like any other, and within the changeset validation logic verify the TOTP challenge. Make sure you save the TOTP secret in the database with all the other user registration fields (but don’t save challenge as it’s a short lived single use parameter).
For authentication just provide the username, password and TOTP challenge field on the sign in form and again validate the TOTP challenge using the users TOTP secret on submit in your context.
I‘d always make 2FA a setting to enable/setup after registration and if it shall be „required“ lock features behind that being done for a user. That way registration doesn‘t get unnecessarily complex.
What I outlined is the minimal implementation to make it work but I agree it’s not ideal if TOTP is optional for your use-case.
If TOTP is user discretion then it makes sense to streamline the registration and provide TOTP setup through profile settings or as a suggestion after email verification.
The work I do requires multi-factor authentication as a regulatory requirement, i.e. it’s not optional and must be enforced from the moment users are onboarded.
The origin of question lies in the sentence If you require session options to be set at runtime, you can use an MFA tuple. The function it designates must return a keyword list.Phoenix.LiveView.Socket — Phoenix LiveView v0.19.5, maybe I’m completely wrong. I know the blog post from dashbit, but during some documention investigation I saw the mentioned sentence and was a little bit confused.