Рекомендуется, чтобы мобильные клиенты периодически обновляли свой токен аутентификации. Это, конечно, зависит от сервера.
Класс TokenAuthentication по умолчанию не поддерживает это, однако вы можете расширить его для достижения этой функциональности.
Например:
from rest_framework.authentication import TokenAuthentication, get_authorization_header
from rest_framework.exceptions import AuthenticationFailed
class ExpiringTokenAuthentication(TokenAuthentication):
def authenticate_credentials(self, key):
try:
token = self.model.objects.get(key=key)
except self.model.DoesNotExist:
raise exceptions.AuthenticationFailed('Invalid token')
if not token.user.is_active:
raise exceptions.AuthenticationFailed('User inactive or deleted')
# This is required for the time comparison
utc_now = datetime.utcnow()
utc_now = utc_now.replace(tzinfo=pytz.utc)
if token.created < utc_now - timedelta(hours=24):
raise exceptions.AuthenticationFailed('Token has expired')
return token.user, token
Также необходимо переопределить представление входа в систему rest framework по умолчанию, чтобы токен обновлялся при каждом входе в систему:
class ObtainExpiringAuthToken(ObtainAuthToken):
def post(self, request):
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
token, created = Token.objects.get_or_create(user=serializer.validated_data['user'])
if not created:
# update the created time of the token to keep it valid
token.created = datetime.datetime.utcnow()
token.save()
return Response({'token': token.key})
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
obtain_expiring_auth_token = ObtainExpiringAuthToken.as_view()
И не забудьте изменить URL-адреса:
urlpatterns += patterns(
'',
url(r'^users/login/?$', '<path_to_file>.obtain_expiring_auth_token'),
)
Если кого-то интересует это решение, но он хочет иметь токен, действительный в течение определенного времени, он заменяется новым токеном, вот полное решение (Django 1.6):
yourmodule / views.py:
yourmodule / urls.py:
ваш проект urls.py (в массиве urlpatterns):
yourmodule / authentication.py:
В настройках REST_FRAMEWORK добавьте ExpiringTokenAuthentication в качестве класса аутентификации вместо TokenAuthentication:
источник
'ObtainExpiringAuthToken' object has no attribute 'serializer_class'
при попытке доступа к конечной точке API. Не уверен, что мне не хватает.Я пробовал ответить @odedfos, но у меня была вводящая в заблуждение ошибка . Вот тот же ответ, исправленный и с правильным импортом.
views.py
authentication.py
источник
Думал, что дам ответ Django 2.0, используя DRY. Кто-то уже создал это для нас, google Django OAuth ToolKit. Доступно с пип,
pip install django-oauth-toolkit
. Инструкции по добавлению токенов ViewSets с маршрутизаторами: https://django-oauth-toolkit.readthedocs.io/en/latest/rest-framework/getting_started.html . Это похоже на официальное руководство.Таким образом, в основном OAuth1.0 был большей безопасностью вчерашнего дня, а именно TokenAuthentication. В наши дни в моде OAuth2.0, чтобы получить необычные истекающие токены. Вы получаете AccessToken, RefreshToken и переменную области для точной настройки разрешений. В итоге вы получите такие кредиты:
источник
Автор спросил
Но все ответы пишут о том, как автоматически менять токен.
Я считаю, что менять токен периодически на токен бессмысленно. Остальные фреймворки создают токен из 40 символов. Если злоумышленник проверяет 1000 токенов каждую секунду, ему требуются
16**40/1000/3600/24/365=4.6*10^7
годы, чтобы получить токен. Не стоит переживать, что злоумышленник будет тестировать ваш токен один за другим. Даже если вы поменяли свой жетон, вероятность угадать ваш жетон остается прежней.Если вас беспокоит, что, возможно, злоумышленники могут получить ваш токен, поэтому вы периодически меняете его, чем после того, как злоумышленник получит токен, он также может изменить ваш токен, чем реальный пользователь будет выгнан.
Что вам действительно нужно сделать, так это не допустить, чтобы злоумышленник получил токен вашего пользователя, используя https .
Кстати, я просто говорю, что изменение токена на токен бессмысленно, изменение токена по имени пользователя и паролю иногда имеет смысл. Возможно, токен используется в какой-то http-среде (вы всегда должны избегать такой ситуации) или какой-либо третьей стороной (в этом случае вы должны создать другой тип токена, использовать oauth2), и когда пользователь делает что-то опасное, например, изменение привязки почтового ящика или удаления учетной записи, вы должны убедиться, что больше не будете использовать исходный токен, потому что он мог быть обнаружен злоумышленником с помощью сниффера или инструментов tcpdump.
источник
Вы можете использовать http://getblimp.github.io/django-rest-framework-jwt
Эта библиотека может генерировать токен со сроком действия
Чтобы понять разницу между токеном DRF по умолчанию и токеном, предоставленным DRF, взгляните на:
Как сделать масштабируемую аутентификацию Django REST JWT с несколькими веб-серверами?
источник
Если вы заметили, что токен похож на файл cookie сеанса, тогда вы можете придерживаться срока жизни файлов cookie сеанса по умолчанию в Django: https://docs.djangoproject.com/en/1.4/ref/settings/#session-cookie-age .
Я не знаю, обрабатывает ли Django Rest Framework это автоматически, но вы всегда можете написать короткий скрипт, который отфильтровывает устаревшие и помечает их как просроченные.
источник
Просто подумал, что добавлю свой, так как это было полезно для меня. Обычно я использую метод JWT, но иногда что-то вроде этого лучше. Я обновил принятый ответ для django 2.1 с правильным импортом.
authentication.py
views.py
источник
просто чтобы продолжать добавлять в ответ @odedfos, я думаю, что были некоторые изменения в синтаксисе, поэтому код ExpiringTokenAuthentication нуждается в некоторой корректировке:
Также не забудьте добавить его в DEFAULT_AUTHENTICATION_CLASSES вместо rest_framework.authentication.TokenAuthentication.
источник