0

So far I used SHA256 to hash passwords (I know, terrible) and now I would like to switch to Argon2.

My problem is that if I understand it correctly I am going to have to store the plain text password in a session variable now.

Now I am storing the SHA256 hash in session variables, and I have a check_user function that check if the user is still logged in for most of my functions.

def check_user(request):
    if 'email' not in request.session or not request.session['email']:
        return False
    if 'pw_hash' not in request.session or not request.session['pw_hash']:
        return False
    try:
        Clients.objects.get(pk=request.session['email'])
    except Clients.DoesNotExist:
        return False
    if request.session['pw_hash'] != Clients.objects.get(pk=request.session['email']).password:
        return False
    return True

If I switch to Argon2, as far as I understand I ll have to store the plain password in the session variable to be able to use PasswordHasher().verify, which is IMO a bad practice.

What is the recommended way for this problem?

Gábor Erdős
  • 3,599
  • 4
  • 24
  • 56
  • So first, why do you have this custom code, when [AuthenticationMiddleware](https://docs.djangoproject.com/en/3.1/ref/middleware/#module-django.contrib.auth.middleware) already has this check. And second, why do you verify the authentication each time? That's not what a "login" session is: a login session verifies authentication data once and then stores the user ID in the session, so you don't have to check credentials every request. See [this part](https://github.com/django/django/blob/9ee693bd6cf4074f04ec51c6f3cfe87cad392f12/django/contrib/auth/__init__.py#L129). –  Apr 02 '21 at 07:45
  • @Melvyn Because the current User implementation is extremely limited. I require email to be a primary key alongside multiple new fields. In the middleware there is an is_authenticated() function, that check authentication for certain functions so I do think that I need to check the credentials in most requests, to avoid session sniffing. – Gábor Erdős Apr 03 '21 at 09:37
  • No one needs email to be primary key. Unique maybe, but primary key, no. Multiple fields that have nothing to do with authentication or authorization should reside on a profile model. Basically, I think you haven't read [this part](https://docs.djangoproject.com/en/3.1/topics/auth/customizing/). > *In the middleware there is an is_authenticated() function* - no there isn't. Can you provide code refs? –  Apr 03 '21 at 10:58
  • @Melvyn Basically around 60% of sites use email as primary keys, so yes it is needed, most sites nowadays dont even have usernames. The relevant part: https://docs.djangoproject.com/en/3.1/topics/auth/default/#limiting-access-to-logged-in-users – Gábor Erdős Apr 03 '21 at 12:50
  • Let's not get hung up on the difference between primary key and [unique](https://docs.djangoproject.com/en/3.1/topics/auth/customizing/#django.contrib.auth.models.CustomUser.USERNAME_FIELD) key and quote unfounded statistics. The part you reference is not in the middleware. And also, it doesn't check the password: it always returns True for any user derived from [AbstractBaseUser](https://github.com/django/django/blob/9ee693bd6cf4074f04ec51c6f3cfe87cad392f12/django/contrib/auth/base_user.py#L90). –  Apr 03 '21 at 22:50

0 Answers0