在 Django 中,如何在装饰函数中的请求对象中设置值并从装饰函数中的请求对象访问它

In Django, how to set value in request object in decorator function and access it from request object in decorated function

我已经使用 django 实现了后端 api。环境详情如下-

环境: 平台:Linux (ubuntu) 框架:Django 1.11.28 编程语言:python 2.7.12(将来计划迁移 3.8) 数据库:Mongodb 3.4

描述: 我使用 django 开发了 web 服务。这些是普通的 Web 服务,而不是 Restful(之前没有完全支持 mongodb 的 Django 休息框架)因此大多数东西都是定制的,而不是按照 Django 标准。

问题详情: 对于身份验证,我使用的是 Azure AD。我写了一个简单的装饰器,它从前端网络 app/mobile 发送的请求接收访问令牌,然后这个装饰器验证令牌和 return 到 view.For 身份验证我正在使用 django-auth-adfs package

装饰器

authorisation.py

def is_authorized(function):
    @wraps(function)
    def authorize(request, *args, **kwargs):
        # access token validation logic
        if validated(token):
            # get user details from access token first_name, last_name etc
            user_info = {"first_name":"foo","last_name":"bar"}
            return function(request, *args, **kwargs)
        else:
            return HttpResponse('Unauthorized', status=401)
return authorize

View.py

@is_authorized
def home_view(request):
    # calling function which decodes access token and return user details.
    # This function contains same code as in decorator except function it returns user_info
    **first_name, last_name = get_userinfo_from_access_token(request)**
return JsonResponse({"data":{"fname":first_name,"lname":last_name}})

如您所见,代码变得混乱且重复。在视图中,我无法访问已在视图中解码的用户详细信息。为了获取用户详细信息,我通过传递请求对象在 get_userinfo_from_access_token() 函数中编写了相同的代码,我认为这离 'ok' 不远。

考虑到我目前的场景和环境,

  1. 您能否解释从请求对象访问用户详细信息的最佳和标准方法
  2. 我创建了很多视图,我正在为每个视图添加 is_authorized 装饰器。是否有任何标准和更好的方法来保护视图。
  3. 我计划将来使用 django rest 框架重写整个代码。如果有人为我提供一些实现 restful Web 服务的参考或指南,以便我可以使用现有代码并减少工作量,我将非常感激。

如果我不清楚任何内容和需要更多详细信息,请告诉我。 提前致谢。

嗯。让我依次给你答案。

  1. 编写一个中间件并根据数据库查询的令牌附加用户。
  2. 创建另一个中间件,仅当用户通过上述 (1) 中间件的身份验证时才允许受保护的路径。
  3. 由于 django 日新月异,如果您在 REST 上实施时单独提出问题会更好。我知道标准,但现在回答它以后可能会过时。

现在回到中间件。 中间件按顺序工作。这些无效的顺序可能不起作用

第一个中间件

class UserResolverMiddleware(MiddlewareMixin):
    """
    A middleware class that adds a ``user`` attribute to the current request.
    """

    def process_request(self, request):
        """

        get token from request header
        validate token
        decode the token
        query on db or attach a fake user with necessary decoded data. 
        attach user object to request like request.user = user
        """

第二个.

from django.http import HttpResponseForbidden
class ProtectedViewMiddleware(MiddlewareMixin):


    def process_request(self, request):

        """
        create a list of URL which is not protected (e.g: login, forget password)
        unprotected_list = ['']
        if request url does not belongs to unprotected_list and request has no attribue user:

            return  HttpResponseForbidden()
        return 
        """