【问题标题】:django-oauth-toolkit : Customize authenticate responsedjango-oauth-toolkit :自定义身份验证响应
【发布时间】:2019-06-19 13:37:08
【问题描述】:

我是 Django OAuth 工具包的新手。我想自定义身份验证响应。

我在 django 应用程序上的身份验证 url 配置是:

url('authenticate/',
    include('oauth2_provider.urls', namespace='oauth2_provider'))

https://django-oauth-toolkit.readthedocs.io/en/latest/install.html

现在,当我启动这个命令时:

curl -X POST -d 'grant_type=password&username=$username&password=$password'
 -u "$client_id:$client_secret" http://127.0.0.1:8000/authenticate/token/

我收到了这个回复:

{
   "access_token": "ATiM10L0LNaldJPk12drXCjbhoeDR8",
   "expires_in": 36000,
   "refresh_token": "II4UBhXhpVDEKWmsUQxDzkj3OMjW1p",
   "scope": "read groups write",
   "token_type": "Bearer"
}

并希望得到这样的回应:

{
   "access_token": "ATiM10L0LNaldJPk12drXCjbhoeDR8",
   "expires_in": 36000,
   "refresh_token": "II4UBhXhpVDEKWmsUQxDzkj3OMjW1p",
   "scope": "read groups write",
   "token_type": "Bearer",
   "member": {
      "id": 1,
      "username": "username",
      "email": "email@gmail.com",
      ....
   }
}

我只想覆盖此响应以添加经过身份验证的用户的信息。 我已经阅读了 django-oauth-toolkit 的文档。而且我没有找到解决问题的方法...

【问题讨论】:

    标签: python django django-rest-framework django-oauth django-oauth-toolkit


    【解决方案1】:

    我能够通过覆盖 TokenView 类来进行此更改 在你的意见中。py

    from django.http import HttpResponse
    from oauth2_provider.views.base import TokenView
    from django.utils.decorators import method_decorator
    from django.views.decorators.debug import sensitive_post_parameters
    from oauth2_provider.models import get_access_token_model, get_application_model
    from oauth2_provider.signals import app_authorized
    import json
    
    
    class CustomTokenView(TokenView):
        @method_decorator(sensitive_post_parameters("password"))
        def post(self, request, *args, **kwargs):
            url, headers, body, status = self.create_token_response(request)
            if status == 200:
                body = json.loads(body)
                access_token = body.get("access_token")
                if access_token is not None:
                    token = get_access_token_model().objects.get(
                        token=access_token)
                    app_authorized.send(
                        sender=self, request=request,
                        token=token)
                    body['member'] = {
                        'id': token.user.id, 
                        'username': token.user.username, 
                        'email': token.user.email
                    }
                    body = json.dumps(body) 
            response = HttpResponse(content=body, status=status)
            for k, v in headers.items():
                response[k] = v
            return response
    

    urls.py 中,只需通过指向自定义视图来覆盖令牌 url。此导入应在 django-oauth-toolkit 的包含之前进行

    url(r"authenticate/token/$", CustomTokenView.as_view(), name="token"),
    url('authenticate/',
        include('oauth2_provider.urls', namespace='oauth2_provider'))
    

    返回现在将包含成员数据

      {
        "access_token": "YtiH9FGwAf7Cb814EjTKbv3FCpLtag", 
        "expires_in": 36000, 
        "token_type": "Bearer", 
        "scope": "read write groups", 
        "refresh_token": "99TyWmCwELrJvymT8m6Z9EPxGr3PJi", 
        "member": {
            "id": 1, 
            "username": "admin", 
            "email": "admin@admin.com"
         }
      }
    

    【讨论】:

    • 这太棒了!
    • from oauth2_provider.signals import app_authorized
    • 看起来不错。但是由于大部分代码已经在TokenView 中,所以不只是调用response = super().post(request, *args, **kwargs) 并使用成员工作更新response 吗?
    【解决方案2】:

    不确定有多少人使用 drf_social_oauth2,但您也可以这样做。这是我的解决方案覆盖drf-social-oauth2 Token View

    url(r"authenticate/token/$", CustomTokenView.as_view(), name="token"),
    

    views.py

    import json
    from rest_framework.response import Response
    from drf_social_oauth2.views import TokenView
    from oauth2_provider.models import get_access_token_model, get_application_model
    from oauth2_provider.signals import app_authorized
    
    
    class CustomTokenView(TokenView):
        def post(self, request, *args, **kwargs):
             mutable_data = request.data.copy()
              request._request.POST = request._request.POST.copy()
               for key, value in mutable_data.items():
                    request._request.POST[key] = value
                url, headers, body, status = self.create_token_response(
                    request._request)
                if status == 200:
                    body = json.loads(body)
                    access_token = body.get("access_token")
                    if access_token is not None:
                        token = get_access_token_model().objects.get(
                            token=access_token)
                        app_authorized.send(
                            sender=self, request=request,
                            token=token)
                        body['member'] = {
                            'id': token.user.id,
                            'username': token.user.username,
                            'email': token.user.email
                        }
                        body = json.dumps(body)
                response = Response(data=json.loads(body), status=status)
    
                for k, v in headers.items():
                    response[k] = v
                return response
    
         
    

    【讨论】:

    • 感谢这里的最佳答案解决了这个问题
    【解决方案3】:

    这个也可以

    import json
    
    from oauth2_provider.models import get_access_token_model
    from oauth2_provider.views import TokenView as OAuth2TokenView
    
    
    class TokenView(OAuth2TokenView):
        def post(self, request, *args, **kwargs):
            response = super().post(request, *args, **kwargs)
            body = json.loads(response.content)
            access_token = body.get("access_token")
            token = get_access_token_model().objects.get(token=access_token)
            body["member"] = {
                "id": token.user.id,
                "email": token.user.email,
                "username": token.user.username,
            }
            response.content = json.dumps(body)
            return response
    

    并在urls.py 中添加

        path("o/token/", TokenView.as_view(), name="token"),
        path("o/", include("oauth2_provider.urls", namespace="oauth2_provider")),
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-15
      • 1970-01-01
      • 2015-08-30
      • 2017-01-13
      • 2016-11-07
      • 1970-01-01
      • 1970-01-01
      • 2014-11-25
      相关资源
      最近更新 更多