DRF auth_token: “non_field_errors”: [ “Unable to log in with provided credentials.”

僤鯓⒐⒋嵵緔 提交于 2020-03-20 06:04:06

问题


Both JWT packages written for Django gave me issues with poor documentation, so I try DRF-auth_token package. This is a good example I followed, Django Rest Framework Token Authentication. You should in theory be able to go to

localhost:8000/api-token-auth/

urls.py:

from django.conf.urls import url, include
from django.contrib import admin
from django.contrib.auth.models import User
from rest_framework.authtoken import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^api/', include('api.urls', namespace='api')),
    url(r'^orders/', include('orders.urls', namespace='orders')),
    url(r'^api-token-auth/', views.obtain_auth_token, name='auth-token'),

]

Getting a token for users is not working so I have rewritten it myself to make it work:

@api_view(['POST'])
def customer_login(request):
    """
    Try to login a customer (food orderer)
    """
    data = request.data

    try:
        username = data['username']
        password = data['password']
    except:
        return Response(status=status.HTTP_400_BAD_REQUEST)

    try:
        user = User.objects.get(username=username, password=password)
    except:
        return Response(status=status.HTTP_401_UNAUTHORIZED)

    try:
        user_token = user.auth_token.key
    except:
        user_token = Token.objects.create(user=user)

    data = {'token': user_token}
    return Response(data=data, status=status.HTTP_200_OK)

My version works:

http://localhost:8000/api/login/customer-login/
{"username": "thisguy@example.com", "password": "wombat"}
-->
{
  "token": "292192b101153b7ced74dd52deb6b3df22ef2c74"
}

The DRF auth_token does not work:

http://localhost:8000/api-token-auth/
{"username": "thisguy@example.com", "password": "wombat"}
-->
{
  "non_field_errors": [
    "Unable to log in with provided credentials."
  ]
}

settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # third party:
    'django_extensions',
    'rest_framework',
    'rest_framework.authtoken',



REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
    )
}

It seems set up correctly. Every user in my DB has a token. Each user is is_authenticated and is_active in DB. Super users can get their token:

localhost:8000/api-token-auth/
{"username": "mysuperuser", "password": "superuserpassword"}
-->
{
  "token": "9297ff1f44dbc6caea67bea534f6f7590d2161b0"
}

for some reason, only super user can get a token:

localhost:8000/api-token-auth/
{"username": "regularguy", "password": "password"}
-->
{
  "non_field_errors": [
    "Unable to log in with provided credentials."
  ]
}

Why can't my users log in and get their token? Thank you


回答1:


I went ahead and did this from the drf token auth docs and didn't run into any problems with superusers, staffusers, or normal users.

Also try following the steps of the official docs instead of that SO answer and see if that fixes the problem - it's possible something changed.

Here were the general steps I took:

  • install django, drf
  • put 'rest_framework' and 'rest_framework.authtoken' in INSTALLED_APPS
  • add 'TokenAuthentication' in my rest_framework settings
  • run migrate
  • create tokens for users (I just did this in urls.py)
  • create the url for token
  • POST http://localhost:8000/token/ {"username": "...", "password": "..."}

If you have the code public anywhere I'd be glad to take a further look and see what I find.




回答2:


Maybe the encryption is to blame. I am facing the same problem. I compared the information stored in mysql of superuser and a common user (let's call it user1). I found a difference. The password of superuser was encrypted, but user1's password wasn't encryted. So I changed user1's password into the superuser's password, then I posted the name and password of user1 to the jwt api and I got the right answer.

And now I find an answer, though it may not be the best one, it should work. I just overwrited the "create" method in "ModelSerializer". step1: copy the "create" method from "ModelSerializer" to your own serializers file step2: change the sentence "instance = ModelClass._default_manager.create(**validated_data)" into "instance = ModelClass._default_manager.create_user(**validated_data)". step3: It worked

]4 [

]5


回答3:


  • I had the same error message when I tried to use this API endpoint :
    " obtain_auth_token" class from rest_framework.authtoken.views ,
    BUT surprise ! The problem was the User serializer in first place ! .

  • Users were created with the API endppint ,their passwords were saved as plain text !, as in this screenshot : User Database
    BUT the TokenAPI endpoint encrypts the password, so from there come the clash! ,

  • I've changed User Serializer class and override create function to use set_password function that hashes the passwords :

    class UserSerializer(serializers.ModelSerializer):
        class Meta:
            model = User
            fields = ['email', 'username', 'password']
            extra_kwargs = {'password': {'write_only': True}}
    
        def create(self, validated_data):
            user = User(
                email=validated_data['email'],
                username=validated_data['username']
            )
            user.set_password(validated_data['password'])
            user.save()
            return user
    
  • Now that I've edited my User Serializer , data are stored like this : User database after modification

  • And So the error : “non_field_errors”: [ “Unable to log in with provided credentials.” stopped showing ! , and the token API endpoint "localhost:8000/api-token-auth/" worked !




回答4:


  1. check username and password
  2. field in the table users.is_active = 1


来源:https://stackoverflow.com/questions/40076254/drf-auth-token-non-field-errors-unable-to-log-in-with-provided-credential

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!