Джанго Остальных Рамок Маркер Проверки Подлинности


Я прочитал руководства Django Rest Framework и сделал все учебники. Все, казалось, имело смысл и работало именно так, как должно. Я получил базовую и сеансовую аутентификацию, работающую, как описано. http://django-rest-framework.org/api-guide

тем не менее, я борюсь с частью аутентификации токена документации, ее немного не хватает или не входит в такую глубину, как tutorials.
http://django-rest-framework.org/api-guide/authentication/#tokenauthentication

Он говорит, что мне нужно создать токены для пользователей, но не указывает, где, в models.py?

мой вопрос:

может ли кто-нибудь объяснить часть аутентификации токена в документации немного лучше для первого таймера?

6 65

6 ответов:

нет, не в вашем models.py -- на стороне моделей вещей, все, что вам нужно сделать, это включить соответствующее приложение (rest_framework.authtoken) в INSTALLED_APPS. Это обеспечит модель токена, которая имеет внешний ключ для пользователя.

что вам нужно сделать, это решить, когда и как эти объекты маркер должен быть создан. В приложении, каждый Пользователь автоматически получает токен? Или только определенные авторизованные пользователи? Или только когда они специально просят об этом?

если каждый пользователь должен всегда иметь токен, на странице, которую вы связали, есть фрагмент кода, который показывает вам, как настроить сигнал для их автоматического создания:

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

(put этой в a models.py файл, где угодно, и он будет зарегистрирован при запуске потока Django)

если токены должны быть созданы только в определенное время, то в вашем коде просмотра вам нужно создать и сохранить токен в соответствующее время:

# 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)

как только токен будет создан (и сохранен), он будет использоваться для аутентификации.

@ian-clelland уже дал правильный ответ. Есть только несколько крошечных кусочков, которые не были упомянуты в его сообщении, поэтому я собираюсь документировать полные процедуры (я использую Django 1.8.5 и DRF 3.2.4):

  1. сделайте следующее до создать суперпользователя. В противном случае суперпользователь не получает свой токен создан.

  2. перейти к settings.py и добавить следующее:

    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. добавьте следующий код в приложение ' 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)
    

    кроме того, если вы хотите быть более явным, создайте файл с именем signals.py под приложение. Поместите код выше в него, а затем в __init__.py, пиши import signals

  4. откройте окно консоли, перейдите к директории проекта и введите следующая команда:

    python manage.py migrate
    python manage.py makemigrations
    

    посмотреть в базе данных таблицу с именем authtoken_token должен быть создан со следующими полями: ключ (это значение токена), создан (дата и время он был создан), user_id (внешний ключ, который ссылается на столбец id таблицы auth_user)

  5. создать суперпользователя с python manage.py createsuperuser. А теперь взгляните на authtoken_token таблица в вашей БД с select * from authtoken_token;, вы должны увидеть новый запись была добавлена.

  6. используя curl или гораздо более простая альтернатива httpie чтобы проверить доступ к вашему api, я использую httpie:

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

    вот и все. Отныне для любого доступа к API необходимо включить в заголовок HTTP следующее значение (обратите внимание на пробелы):

    Authorization: Token your_token_value
    
  7. (необязательно) DRF также предоставляет возможность вернуть маркер пользователя, если вы предоставляете имя пользователя и пароль. Все, что вам нужно сделать, это включить следующее в urls.py:

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

    использование httpie для проверки:

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

    в возвращаемом теле, вы должны увидеть это:

    {
        "token": "blah_blah_blah"
    }
    

вот именно!

просто чтобы добавить мои два цента к этому, если у вас есть пользовательский менеджер пользователей, который обрабатывает создание пользователей (и активацию), вы также можете выполнить эту задачу следующим образом:

from rest_framework.authtoken.models import Token
# Other imports

class UserManager(BaseUserManager):

    def create_user(self, **whatever_else):
        """
        This is your custom method for creating user instances. 
        IMHO, if you're going to do this, you might as well use a signal.

        """
        user = self.model(**whatever_params)
        .... #Method ramblings that somehow gave us a user instance
        Token.objects.create(user=user)

    #You may also choose to handle this upon user activation. 
    #Again, a signal works as well here.

    def activate_user(**activation_ramblings):
        .... #Method ramblings that somehow gave us a user instance
        Token.objects.create(user=user)

Если у вас уже есть пользователи, то вы можете опуститься в оболочку python в вашем терминале и создать токены для всех пользователей в вашей БД.

>>>from *whatever import User
>>>from rest_framework.authtoken.models import Token 
>>>for user in User.objects.all():
>>>...    Token.objects.create(user=user)

это все, что она написала люди! Надеюсь, это кому-то поможет.

на Django 1.8.2 и REST framework 3.3.2 после всего вышесказанного было недостаточно, чтобы включить аутентификацию на основе токенов.

хотя параметр REST_FRAMEWORK указан в файле настроек django, требуется представление на основе функций @api_view decorator:

from rest_framework.decorators import api_view

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

в противном случае аутентификация токенов не выполняется вообще

есть более чистый способ получить маркер пользователя.

просто запустите manage.py shell

а то

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

тогда запись должна быть найдена в таблице DB_Schema.authtoken_token

в дополнение к отличным ответам здесь, я хотел бы упомянуть лучший подход к аутентификации токенов: JSON Web Token Authentication. Реализация, предлагаемая http://getblimp.github.io/django-rest-framework-jwt/ очень проста в использовании.

преимущества объясняются более подробно в ответ.