3

I'm transferring a database to a new project and more precisely the users. Don't ask me why but the passwords in the old database were hashed with md5 and then with sha256.

I'm using django-rest-auth to manage login.

url(r'^api/rest-auth/', include('rest_auth.urls')),

I added a custom authentication method:

REST_FRAMEWORK = {
  'DEFAULT_AUTHENTICATION_CLASSES': (
     'users.auth.OldCustomAuthentication',
     'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
  )
}

Here is my auth file:

class OldCustomAuthentication(BaseAuthentication):
    def authenticate(self, request):
        try:
            password = request.POST['password']
            email = request.POST['email']
        except MultiValueDictKeyError:
            return None

        if not password or not email:
            return None

        password = hashlib.md5(password.encode())
        password = hashlib.sha256(password.hexdigest().encode())

        try:
            user = User.objects.get(email=email, password=password.hexdigest())
        except User.DoesNotExist:
            return None

        # User is found every time
        print('FOUND USER', user)
        return user, None

But I still get an error when I request http://apiUrl/rest-auth/login/:

{
    "non_field_errors": [
        "Unable to log in with provided credentials."
    ]
}

Do you have any idea? Or maybe I'm doing it in a wrong way.

Thank you in advance.

Jeremy.

9
  • I'm pretty sure that there is salt used when hashing. Here is the doc: docs.djangoproject.com/en/2.1/topics/auth/passwords so its not just hash of password. Commented Feb 7, 2019 at 22:57
  • Does your return line need to be a tuple instead of two variables? Documentation for reference (see code sample): django-rest-framework.org/api-guide/authentication/#example Commented Feb 7, 2019 at 22:59
  • The thing is I find my user in my new database. I just want to know what I need to return to say "Hey, you're connected". I thought returning user, None would let django-rest-framework know that this user used the good credentials. And @MrName, with or without parenthesis, it's the same Commented Feb 7, 2019 at 23:00
  • Have tried to remove JSONWebTokenAuthentication to see if it works this way? Commented Feb 7, 2019 at 23:09
  • Yes, and I still have the same response from the endpoint /rest-auth/login/ ... You can see a screenshot of the debugger here: imgur.com/a/uhzqM2a Commented Feb 7, 2019 at 23:10

1 Answer 1

2

Following the advice of @MrName I managed to solve my issue.

So I deleted DEFAULT_AUTHENTICATION_CLASSES in my settings and added this:

 REST_AUTH_SERIALIZERS = {
    'LOGIN_SERIALIZER': 'users.auth.LoginSerializer'
 }

Then I copy pasted the original serializer and modified the function _validate_email with:

def _validate_email(self, email, password):
    user = None

    if email and password:
        user = self.authenticate(email=email, password=password)

        # TODO: REMOVE ONCE ALL USERS HAVE BEEN TRANSFERED TO THE NEW SYSTEM
        if user is None:
            password_hashed = hashlib.md5(password.encode())
            password_hashed = hashlib.sha256(password_hashed.hexdigest().encode())
            try:
                user = User.objects.get(email=email, password=password_hashed.hexdigest())
            except ObjectDoesNotExist:
                user = None
    else:
        msg = _('Must include "email" and "password".')
        raise exceptions.ValidationError(msg)

    return user
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.