Подтвердить что ты не робот

Аутентификация маркера Django Rest Framework

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

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

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

Мой вопрос:

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

4b9b3361

Ответ 1

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

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

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

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

(поместите это в файл 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)

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

Ответ 2

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

  • Сделайте следующие вещи ПЕРЕД, создав суперпользователя. В противном случае суперпользователь не получит свой токен.

  • Перейдите в 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',
        )
    }
    
  • Добавьте следующий код в myapp 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)
    

    В качестве альтернативы, если вы хотите быть более явным, создайте файл с именем signal.py в проекте myapp. Поместите в него код, затем в __ init __. Py, напишите import signals

  • Откройте консольное окно, перейдите в каталог проекта и введите следующую команду:

    python manage.py migrate
    python manage.py makemigrations
    

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

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

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

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

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

    Authorization: Token your_token_value
    
  • (Необязательно) 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"
    }
    

Что это!

Ответ 3

В 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():
       ...

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

Ответ 4

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

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 в своем терминале и создать токены для всех пользователей вашего db.

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

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

Ответ 5

Существует более чистый способ получить токен пользователя.

просто запустите оболочку manage.py

а затем

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

Ответ 6

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

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