Gal*_*man 12 python django oauth-2.0 django-rest-framework django-oauth
我正在使用最新的Django OAuth2 Toolkit(0.10.0)和Python 2.7,Django 1.8和Django REST框架3.3
使用时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/
Run Code Online (Sandbox Code Playgroud)
一个新的访问令牌和刷新令牌创建.在令牌超时之前,旧的访问和刷新令牌仍然可用!
我的问题:
我发现的一个解决方案是REST Framework OAuth一次为一个访问令牌提供配置.我并不急于使用该提供商,但我可能不会有选择.
Ein*_*hen 14
如果您想在发布新签名之前删除所有先前的访问令牌,可以使用这个问题的简单解决方案:创建自己的令牌视图提供程序!
下面的代码可能会帮助您实现这种功能:
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)
Run Code Online (Sandbox Code Playgroud)
您应该注意的部分是Try-Except块.在那里,我们找到了访问令牌并删除它们.在我们创建一个新的之前.
您可以查看如何使用OAuthLib创建自己的提供程序.此外,这也可能有用:django-oauth-toolkit中的TokenView.你可以在那里看到原始的Apiview.如你所说,你正在使用这个包.
至于refresh_token,如前面在其他答案中所提到的,你不能做你要求的.查看oauthlib密码grunt类型的代码时,您会看到在初始化时,refresh_token设置为True.除非你自己更改Grunt类型,否则无法完成.
但是你可以使用访问令牌做同样的事情.创建令牌,然后删除刷新令牌.
我需要的是每次用户请求新的访问令牌时,旧的访问令牌将变为无效,无法使用并将被删除.
当你要求一个新的令牌似乎是一个预期的行为.在要求新的之前,你不可能撤销现有的吗?
更新
RequestValidator并覆盖方法save_bearer_token.在此方法中,在与AccessToken模型实例创建相关的代码及其.save()方法之前,您可以查询(类似于此)以查看是否已在此DB中为此用户保存了AccessToken.如果找到,则可以从数据库中删除现有令牌.
我强烈建议作出这一改变配置,如果你改变主意在未来的(毕竟多个令牌发放给类似的原因此)
更简单的解决方案是拥有自己的验证器类,可能是继承oauth2_provider.oauth2_validators.OAuth2Validator和覆盖的类save_bearer_token.这个新的类应给予OAUTH2_VALIDATOR_CLASS在settings.py
此外,有没有一种方法,密码grunt类型不会创建刷新令牌.我在我的申请中没有任何用处.
Django OAuth Toolkit依赖于OAuthLib.
使refresh_token可选归结为此行中oAuthLib类中的create_token方法,密码授权类在此处.正如您所看到的,此类的方法采用默认设置为的参数.该值用于该行中同一类的方法BearerToken__init__refresh_tokenTruecreate_token_response
token = token_handler.create_token(request, self.refresh_token)
Run Code Online (Sandbox Code Playgroud)
create_token_response在方法OAuthLibCore类的Django的OAuth工具包是一个,我相信,调用相应create_token_response的OAuthLib.观察这个类的方法的用法self.server及其初始化,__init__该类只有作为参数传递的验证器,但没有任何相关的refresh_token.
将其与OAuthLib Imlicit grant type的create_token_response方法进行比较,该方法明确地做了
token = token_handler.create_token(request, refresh_token=False)
Run Code Online (Sandbox Code Playgroud)
不创建refresh_token在所有
所以,除非我在这里错过了什么,tldr,我不认为Django OAuth工具包暴露了可选的功能refresh_token.