Django Rest Framework Token Authentication

前端 未结 7 1261
北荒
北荒 2020-12-07 08:24

I have read the Django Rest Framework Guides and done all the tutorials. Everything seemed to make sense and work just how it should. I got basic and session authentication

相关标签:
7条回答
  • 2020-12-07 08:57

    JSON Web Token Authentication is a better alternative than Token Authentication. This project has implemented JWT Auth with Django (http://getblimp.github.io/django-rest-framework-jwt/) but currently the project is unmaintained.

    For alternatives you can follow : https://github.com/davesque/django-rest-framework-simplejwt

    0 讨论(0)
  • 2020-12-07 08:59

    No, not in your models.py -- on the models side of things, all you need to do is include the appropriate app (rest_framework.authtoken) in your INSTALLED_APPS. That will provide a Token model which is foreign-keyed to User.

    What you need to do is decide when and how those token objects should be created. In your app, does every user automatically get a token? Or only certain authorized users? Or only when they specifically request one?

    If every user should always have a token, there is a snippet of code on the page you linked to that shows you how to set up a signal to create them automatically:

    @receiver(post_save, sender=User)
    def create_auth_token(sender, instance=None, created=False, **kwargs):
        if created:
            Token.objects.create(user=instance)
    

    (put this in a models.py file, anywhere, and it will be registered when a Django thread starts up)

    If tokens should only be created at certain times, then in your view code, you need to create and save the token at the appropriate time:

    # View Pseudocode
    from rest_framework.authtoken.models import Token
    
    def token_request(request):
        if user_requested_token() and token_request_is_warranted():
            new_token = Token.objects.create(user=request.user)
    

    Once the token is created (and saved), it will be usable for authentication.

    0 讨论(0)
  • 2020-12-07 09:00

    In addition to the excellent answers here, I'd like to mention a better approach to token authentication: JSON Web Token Authentication. The implementation offered by http://getblimp.github.io/django-rest-framework-jwt/ is very easy to use.

    The benefits are explained in more detail in this answer.

    0 讨论(0)
  • 2020-12-07 09:01

    There is a cleaner way to get the user token.

    simply run manage.py shell

    and then

    from rest_framework.authtoken.models import Token
    from django.contrib.auth.models import User
    u = User.objects.get(username='admin')
    token = Token.objects.create(user=u)
    print token.key
    

    then a record should be found in table DB_Schema.authtoken_token

    0 讨论(0)
  • 2020-12-07 09:02

    On Django 1.8.2 and rest framework 3.3.2 following all of the above was not enough to enable token based authentication.

    Although REST_FRAMEWORK setting is specified in django settings file, function based views required @api_view decorator:

    from rest_framework.decorators import api_view
    
    @api_view(['POST','GET'])
    def my_view(request):
        if request.user.is_authenticated():
           ...
    

    Otherwise no token authentication is performed at all

    0 讨论(0)
  • 2020-12-07 09:07

    @ian-clelland has already provided the correct answer. There are just a few tiny pieces that wasn't mentioned in his post, so I am going to document the full procedures (I am using Django 1.8.5 and DRF 3.2.4):

    1. Do the following things BEFORE you create the superuser. Otherwise, the superuser does not get his/her token created.

    2. Go to settings.py and add the following:

      INSTALLED_APPS = (
          'rest_framework',
          'rest_framework.authtoken',
          'myapp',
      )
      
      REST_FRAMEWORK = {
          'DEFAULT_PERMISSION_CLASSES': (
              'rest_framework.permissions.IsAuthenticated',
          ),
          'DEFAULT_AUTHENTICATION_CLASSES': (
              'rest_framework.authentication.TokenAuthentication',
          )
      }
      
    3. Add the following code in myapp's models.py:

      from django.db.models.signals import post_save
      from django.dispatch import receiver
      from rest_framework.authtoken.models import Token
      from django.conf import settings
      
      # This code is triggered whenever a new user has been created and saved to the database
      @receiver(post_save, sender=settings.AUTH_USER_MODEL)
      def create_auth_token(sender, instance=None, created=False, **kwargs):
          if created:
              Token.objects.create(user=instance)
      

      Alternatively, if you want to be more explicit, create a file named signals.py under myapp project. Put the code above in it, then in __init__.py, write import signals

    4. Open up a console window, navigate to your project dir, and enter the following command:

      python manage.py migrate
      python manage.py makemigrations
      

      Take a look in your database, a table named authtoken_token should be created with the following fields: key (this is the token value), created (the datetime it was created), user_id (a foreign key that references the auth_user table's id column)

    5. create a superuser with python manage.py createsuperuser. Now, take a look at the authtoken_token table in your DB with select * from authtoken_token;, you should see a new entry has been added.

    6. Using curl or a much simpler alternative httpie to test access to your api, I am using httpie:

      http GET 127.0.0.1:8000/whatever 'Authorization: Token your_token_value'
      

      That's it. From now on, for any API access, you need to include the following value in the HTTP header (pay attention to the whitespaces):

      Authorization: Token your_token_value
      
    7. (Optional) DRF also provides the ability to return a user's token if you supply the username and password. All you have to do is to include the following in urls.py:

      from rest_framework.authtoken import views
      
      urlpatterns = [
          ...
          url(r'^api-token-auth/', views.obtain_auth_token),
      ]
      

      Using httpie to verify:

      http POST 127.0.0.1:8000/api-token-auth/ username='admin' password='whatever'
      

      In the return body, you should see this:

      {
          "token": "blah_blah_blah"
      }
      

    That's it!

    0 讨论(0)
提交回复
热议问题