将自定义字段添加到Django Rest Framework生成令牌

时间:2019-10-22 12:22:59

标签: oauth-2.0 django-rest-framework

使用Django Rest Framework,当我想生成令牌时,我尝试添加自定义字段(氏族),它应该是必填字段和现有氏族。

赞:

curl -X POST -d "grant_type=password&username=username&password=password&client_id=client_id&client_secret=client_secret&clan=ABCDEF" http://localhost:8000/o/token/

我的用户模型:

class User(AbstractUser):
    """
    User model.
    """
    clans = models.ManyToManyField(Clan, related_name='Users')

我的其余框架设置:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'apps.core.api.pagination.StandardPagination',
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAdminUser',
    ),
    'DEFAULT_FILTER_BACKENDS': (
        'django_filters.rest_framework.DjangoFilterBackend',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'EXCEPTION_HANDLER': 'apps.core.exceptions.api.custom_exception_handler',
}

然后我想要一个经典的回答:

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

1 个答案:

答案 0 :(得分:0)

最后我找到了解决方法:

您需要覆盖 oauth2_provider.views.base 中的类 TokenView ,然后覆盖 post方法

class MyCustomToken(TokenView):
    """
    ....
    """
    @method_decorator(sensitive_post_parameters("password"))
    def post(self, request, *args, **kwargs):
        """
        ...
        """
        # Check if the clan parameter is given in parameter.
        clan_parameter = request.POST.get('clan', False)
        if not clan_parameter:
            return JsonResponse(
                {'clan': 'Parameter is required.'},
                status = 401
            )
        url, headers, body, status = self.create_token_response(request)
        if status == 200:
            access_token = json.loads(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)
        response = HttpResponse(content=body, status=status)

        for k, v in headers.items():
            response[k] = v
        return response