Аутентификация маркера 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?
Мой вопрос:
Может кто-нибудь объяснить часть аутентификации токена в документации немного лучше для первого таймера?
Ответы
Ответ 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/, очень проста в использовании.
Преимущества объясняются более подробно в этом ответе.
Ответ 7
JSON Web Token Authentication является лучшей альтернативой, чем Token Authentication. В этом проекте реализована аутентификация JWT с Django (http://getblimp.github.io/django-rest-framework-jwt/), но в настоящее время проект не поддерживается.
Для альтернативы вы можете следовать: https://github.com/davesque/django-rest-framework-simplejwt