codebuddies / backend

CodeBuddies back-end
https://codebuddies.org
GNU General Public License v3.0
20 stars 25 forks source link

Authentication and Sign Up Strategy #101

Closed angelocordon closed 4 years ago

angelocordon commented 4 years ago

This is originally from https://github.com/codebuddies/frontend/issues/77 that was started by @lpatmo but we thought it might better be discussed here.

The original discussion:

Magic links where user would input their email and get a link to signup

Let's discuss advantages/disadvantages, including:

Can signup magic links exist alongside a normal username/password flow? Can they exist alongside GitHub auth? What would the implementation look like?

angelocordon commented 4 years ago

I'd like to avoid social auth for now, and revisit the need for us to implement it. I think some of the complexities that might arise could be linking accounts to the correct profiles. Perhaps if anything, we should retain emails as the main attribute to a user account. I could see why we might want to give other options, but they seem likely to be small edge cases.

Potentially, I really like the experience of how Notion handles their authentication. A user signs in and signs up with an email address, and a temporary password gets emailed to them, which is a set of words stringed together with dashes (i.e., some-random-password-for-you). And that's what gets used to authenticate. I like it because it reduces the risk of people reusing passwords, or removes the needs for people to make one for another account.

BethanyG commented 4 years ago

As far as I understand, Django uses a username as an account identifier, and an email is not required, but a strong password (we can determine the criteria for what constitutes strong) is required. We can require an email...but we should discuss if we want to do that, and if we want to always persist it. That would also require a codebuddies API change.

Just for some touchpoints: here is the Django Auth Docs.

Our current setup includes:

  1. A custom user model, where we can add fields we want to track outside of the ones provided by the default Django user model.

  2. The default password storage, based on PBKDF2 with a SHA256 hash

  3. The default authentication backend and the django-allauth AuthenticationBackend - "social auth" - although we are not currently using it. Here are more available authentication backends.

  4. Django DRF, which has it's own methods and settings for authentication. Our current setting is rest_framework.permissions.IsAuthenticated.

  5. Django-rest-framework-jwt, to provide JWT tokens once a user is authenticated through the stack above. django-rest-framework-jwt on GitHub

Some potential libraries/extensions:

  1. django-authlib, which can provide an additional layer over the above stack so that users do not have a password, but are rather sent a cryptographically signed link via email, or are "authed" through a third party providers email.

  2. django-sesame, which can provide "magic links" that include a token. There are multiple caveats here, one of which is no clear support of DRF or JWT as we currently have it implemented. There are also multiple security concerns with token issuance and URL interception. Here is a how-to I quickly dug up.

  3. I haven't dug into this at all, but here is a blog post on secret links and security in Django on a per-URL or view basis.

  4. Django does provide for "generating" passwords via the make_password() function, so we could call that to generate a password for a user.

  5. django-extensions - which we use in our dev env, but not in production, can also be used to generate passwords.

lpatmo commented 4 years ago

A sixth library we can add to the list for magic links:

drfpasswordless (found on the bottom of the DRF page)

BethanyG commented 4 years ago

Closing this in favor of discussion #178.