Note to those who might be implementing multiple forms of authentication in a Django app: t some point, either through a popular boilerplate or by finding it online, you may be tempted to use https://github.com/pennersr/django-allauth to unify multiple authentication mechanisms. Be very, very careful before using this library. Not only do seemingly simple things require digging into the codebase and finding something to override or monkey-patch, but there are many ways in which denormalized data (such as a user's primary email address as a column therein, which is duplicative with a primary-marked row in a one-to-many table of user email addresses) can become desynchronized. It may still be the right choice for your business, but it comes with massive technical debt. Caveat emptor. If the self-rolled techniques in the OP are sufficient for your use case, consider just using what comes with Django and what you roll yourself.