phx.gen.auth two-factor authentication (2FA)

310 views
Skip to first unread message

Damir Vandic

unread,
Aug 31, 2021, 4:38:57 AM8/31/21
to phoenix-core
Is there any interest for (optional) support for 2FA in the phx.gen.auth task? We've been adding this each time manually and I figured it might be useful to have this built-in in the generator? Or is this considered out-of-scope?

José Valim

unread,
Aug 31, 2021, 5:11:12 AM8/31/21
to phoeni...@googlegroups.com
Hi Damir,

I think that's a good idea and the original application that we extracted mix phx.gen.auth from did have 2FA. At the same time, I think 2FA is best implemented with LiveView, so there is at least a discussion on how we would integrate it. For example, would we move all of settings to LiveView? Or would we simply render the 2FA widget? Should we try to componentize the 2FA bits? So overall I think there is a bit more exploration in the design before we move forward with this.

If you are willing, it could be really helpful if you wrote an article on your process. It could serve as documentation for you and help others. :)

On Tue, Aug 31, 2021 at 10:39 AM 'Damir Vandic' via phoenix-core <phoeni...@googlegroups.com> wrote:
Is there any interest for (optional) support for 2FA in the phx.gen.auth task? We've been adding this each time manually and I figured it might be useful to have this built-in in the generator? Or is this considered out-of-scope?

--
You received this message because you are subscribed to the Google Groups "phoenix-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to phoenix-core...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/phoenix-core/b6005ad1-f121-4aad-a2ed-058b550fa4bfn%40googlegroups.com.

Damir Vandic

unread,
Aug 31, 2021, 5:40:54 AM8/31/21
to phoenix-core
> I think 2FA is best implemented with LiveView, so there is at least a discussion on how we would integrate it. For example, would we move all of settings to LiveView? Or would we simply render the 2FA widget?

I assume here you mean the part where the user has to scan the QR-code? In our app we have done this in LiveView because the whole app is implemented in LiveView :), but I think using just regular server-side rendered views is fine as default, or are there specific advantages of LiveView for this usecase that I'm missing here?

> Should we try to componentize the 2FA bits
As dependencies we used nimble_totp (thanks for that ;)) and eqrcode. Different from the password hashing libraries I think it's ok to use a hardcoded set of dependencies (for now) because choosing different dependencies (in theory) should not change the behavior. TOTP and QR-codes are more or less "standardized", whereas bcrypt vs pbkdf2 gives you different limitations and security properties. Overall, I think configuration for the TOTP specifics (period, uri label, issuer, etc.) would be sufficient but I'd love to hear your opinion on this.

> If you are willing, it could be really helpful if you wrote an article on your process. It could serve as documentation for you and help others. :)
That's a great idea! I think we'll try applying our 2FA approach on a fresh phoenix 1.6 project and write an article about it.

Op dinsdag 31 augustus 2021 om 11:11:12 UTC+2 schreef José Valim:

José Valim

unread,
Aug 31, 2021, 5:55:43 AM8/31/21
to phoeni...@googlegroups.com
Yup, those are the same deps we picked. I forgot to say but our implementation was open sourced here: https://github.com/dashbitco/bytepack_archive

Now that I revisit the code, I just realized that we also implemented backup codes, and now I am thinking a separate generator, such as mix phx.gen.2fa is likely a better deal:


Then the manual changes are likely to:

1. Change the sessions controller to redirect to totp if pending:


2. Redirect to the totp page if pending:


Which are both minimal. For the second one, I would likely change it though. Today it has some hardcoded paths and I would likely do something like this instead:

    get "/users/totp", UserTOTPController, assigns: %{skip_totp_check: true}

And then check if the skip_totp_check is not set instead of the hardcoded path.

> I assume here you mean the part where the user has to scan the QR-code? In our app we have done this in LiveView because the whole app is implemented in LiveView :), but I think using just regular server-side rendered views is fine as default, or are there specific advantages of LiveView for this usecase that I'm missing here?

It is just much easier with LiveView because we can immediately give feedback if the TOTP code is valid or not, without having to store it in the session, send separate requests, etc.


José Valim

unread,
Aug 31, 2021, 5:57:24 AM8/31/21
to phoeni...@googlegroups.com
Oh, of course it has its own migrations too, as well as its own view and templates. I still think a good chunk of the UI bits can be compartmentalized though, but I haven't explored this route yet.

Damir Vandic

unread,
Aug 31, 2021, 6:18:02 AM8/31/21
to phoenix-core
> and now I am thinking a separate generator, such as mix phx.gen.2fa is likely a better deal:

That's also an interesting approach, and the generated tests would ensure that the manual changes are applied correctly?

Thanks for the pointers, I'll use those as a starter for the documented example project. Backup codes are something that we don't have currently but it should definitely be in there!

> It is just much easier with LiveView because we can immediately give feedback if the TOTP code is valid or not, without having to store it in the session, send separate requests, etc.

Ah yes that's indeed easier with LiveView. For us it's fine to use a LiveView widget that one should embed on the settings page as for most projects we default to LiveView anyways. I'm not sure what the general policy is around depending on LiveView going forward from 1.6? It's enabled by default if I remember correctly so it's also fine to depend on it by default for these generators?

Op dinsdag 31 augustus 2021 om 11:57:24 UTC+2 schreef José Valim:

José Valim

unread,
Aug 31, 2021, 6:35:05 AM8/31/21
to phoeni...@googlegroups.com
If it is an additional generator, then I think it is fine to say it is LiveView required. I would probably start with it as a separate generator though, like mix phx.gen.auth (which perhaps can be used as an example/foundation?).

Damir Vandic

unread,
Aug 31, 2021, 6:45:18 AM8/31/21
to phoenix-core
> If it is an additional generator, then I think it is fine to say it is LiveView required.

Clear.

> I would probably start with it as a separate generator though, like mix phx.gen.auth (which perhaps can be used as an example/foundation?).

Oh yeah that's a good idea. I'll look into phx.gen.auth and use that as the foundation.

Op dinsdag 31 augustus 2021 om 12:35:05 UTC+2 schreef José Valim:

M R

unread,
Apr 6, 2022, 1:50:36 PM4/6/22
to phoenix-core
It's an interesting idea!

would be nice if it also supports U2F as descried here  https://www.peterullrich.com/uf2-with-phoenix-live-view 

Reply all
Reply to author
Forward
0 new messages