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

时间:2020-03-13 12:13:24

标签: python django django-rest-framework django-authentication django-middleware

我已经使用Django实现了后端api。环境详细信息为-

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

说明: 我已经使用django开发了Web服务。这些是普通的Web服务,不是Restful的(以前没有为Django rest框架提供对mongodb的完全支持),因此大多数内容不是按照django标准定制的。

问题详细信息: 为了进行身份验证,我使用的是Azure AD。我编写了一个简单的装饰器,该装饰器从前端Web应用程序/移动设备发送的请求中接收访问令牌,然后该装饰器将验证令牌并返回视图。对于身份验证,我使用的是django-auth-adfs包

装饰器

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'。

  • 我需要按照django标准进行操作的方法,并且大多数django开发人员都遵循该方法。如果需要,我是否需要实现一些身份验证后端或django中间件?

考虑我当前的情况和环境,

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

如果我不清楚任何内容,并且需要更多详细信息,请告诉我。 预先感谢。

1 个答案:

答案 0 :(得分:1)

好吧。让我按顺序给出您的答案。

  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 
        """