2016-04-03 3 views
12

Я использую последнюю Django OAuth2 Toolkit (0.10.0) с Python 2.7, Django 1.8 и Django REST рамки 3,3Создание маркера единого доступа с Django oauth2 Toolkit

При использовании grant_type=password, я заметил некоторое странное поведение, что в любое время пользователь запрашивает новый маркер доступа:

curl -X POST -d "grant_type=password&username=<user_name>&password=<password>" -u"<client_id>:<client_secret>" http://localhost:8000/o/token/ 

нового маркера доступ и обновление токена создан. старый токен доступа и обновления до сих пор полезен до тайм-аута маркера!

Мои вопросы:

  • Что мне нужно, чтобы каждый раз, когда пользователь запрашивает новый маркер доступа, старый станет недействительным, непригодным для использования и будут удалены.
  • Кроме того, есть способ, которым пароль типа grunt не создаст обновить токен . Я не использую это в своем приложении.

Одно решение, которое я нашел, это то, что REST Framework OAuth обеспечивает конфигурацию для Одного Токера доступа за раз. Я не хочу использовать этого провайдера, но у меня не будет выбора.

ответ

12

Если вы хотите удалить все предыдущие маркеры доступа перед выпуском нового, есть простое решение этой проблемы: Сделайте свой собственный поставщик токенов!

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

from oauth2_provider.models import AccessToken, Application 
from braces.views import CsrfExemptMixin 
from oauth2_provider.views.mixins import OAuthLibMixin 
from oauth2_provider.settings import oauth2_settings 

class TokenView(APIView, CsrfExemptMixin, OAuthLibMixin): 
    permission_classes = (permissions.AllowAny,) 

    server_class = oauth2_settings.OAUTH2_SERVER_CLASS 
    validator_class = oauth2_settings.OAUTH2_VALIDATOR_CLASS 
    oauthlib_backend_class = oauth2_settings.OAUTH2_BACKEND_CLASS 

    def post(self, request): 
     username = request.POST.get('username') 
     try: 
      if username is None: 
       raise User.DoesNotExist 
      AccessToken.objects.filter(user=User.objects.get(username=username), application=Application.objects.get(name="Website")).delete() 
     except Exception as e: 
      return Response(e.message,status=400) 

     url, headers, body, status = self.create_token_response(request) 
     return Response(body, status=status, headers=headers) 

Часть вы должны обратить внимание, это Try-за исключением блока. Там мы находим токены доступа и удаляем их. Все перед созданием нового.

Вы можете посмотреть, как создать свой собственный Provider using OAuthLib. Кроме того, это может быть полезно также: TokenView in django-oauth-toolkit. Вы можете увидеть там оригинальный Apiview. Как вы сказали, вы использовали этот пакет.

Что касается refresh_token, как уже упоминалось в других ответах здесь, вы не можете делать то, что вы просите. При просмотре кода oauthlib пароля типа grunt вы увидите, что при его инициализации refresh_token имеет значение True. Если вы не измените тип Grunt самостоятельно, это невозможно.

Но вы можете сделать то же самое, что и мы, с помощью токенов доступа. Создайте токен, а затем удалите токен обновления.

+0

Могу ли я использовать этот метод, чтобы не требовать имя пользователя и пароль вообще? И вместо этого требуется пароль приложения или что-то еще. – shenk

5

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

Предоставление нового токена, когда вы запрашиваете его, похоже на ожидаемое поведение. Разве вам не возможно revoke существующий, прежде чем просить новый?

Update


Если вы решили сохранить только один маркер - Класс OAuth2Validator наследует OAuthLib-х RequestValidator и переопределяет метод save_bearer_token. В этом методе перед кодом, связанным с созданием экземпляра AccessToken model, и его методом .save() вы можете запросить (аналогично this), чтобы узнать, есть ли в этом пользователе AccessToken, сохраненный в БД для этого пользователя. Если найден, существующий токен можно удалить из базы данных.

я настоятельно рекомендую сделать это изменение настраивается, в случае, если вы измените свое мнение в будущем (после того, как все несколько маркеров выпускаются по причинам, как this)

Более простое решение, чтобы иметь свой собственный класс валидатора, вероятно, один, который наследует oauth2_provider.oauth2_validators.OAuth2Validator и переопределяет save_bearer_token. Этот новый класс следует за OAUTH2_VALIDATOR_CLASS в settings.py


Кроме того, есть ли способ, что пароль типа хрюкать обыкновение создавать попробуйте обновить маркер. Я не использую это в своем приложении.

Django OAuth Toolkit зависит от OAuthLib.

Создание refresh_token опциональный сводится к create_token метода в BearerToken классе oAuthLib в this line и класс для гранта пароль является here. Как вы можете видеть, метод __init__ для этого класса принимает аргумент refresh_token, который по умолчанию установлен в True. Это значение используется в create_token_response метода того же класса на линии

token = token_handler.create_token(request, self.refresh_token) 

create_token_response метод в OAuthLibCore классе Django OAuth инструментария является один, я считаю, вызывает в OAuthLib соответствующий create_token_response. Обратите внимание на использование self.server и его инициализацию в методе __init__ этого класса, который имеет только валидатор, переданный в качестве аргумента, но ничего не связанный с refresh_token.

Сравните это с create_token_response методом OAuthLib Imlicit grant type «s, который явно делает

token = token_handler.create_token(request, refresh_token=False) 

, чтобы не создавать refresh_token на всех

Так что, если я не пропустил что-то здесь, tldr, я не думаю, Инструментарий Django OAuth предоставляет функцию необязательного refresh_token.

+0

аннулирование токена - это запрос, который я не хочу делать. Целью здесь является предоставление только одного доступа для пользователя на одной машине. Я не хочу, чтобы один и тот же пользователь заходил в систему сразу. – Gal

+1

@Gal, пожалуйста, см. Мое Редактирование, описывающее изменения, которые должны быть выполнены в Django Oauth Toolkit – LearnerEarner

+0

Я не хочу менять основной класс OAuthLib. Весь смысл использовать его как пакет, так это то, что я его не изменю. С другой стороны, использование проверки класса может быть хорошей идеей. – Gal

Смежные вопросы