我的任务是创建一个基本的装饰器,我们可以使用基本的HTTP身份验证来装饰一些特定的django视图。
我有以下装饰者:
def basic_auth(func):
def process_request(self, request):
if request.META.get("HTTP_AUTHORIZATION"):
encoded_auth = request.META.get("HTTP_AUTHORIZATION")
encoded_auth = encoded_auth[6:]
auth = base64.b64decode(encoded_auth)
auth_email = auth.split(":")[0]
auth_password = auth.split(":")[1]
if (auth_email == settings.BASIC_AUTH_EMAIL) and (auth_password == settings.EMAIL_HOST_PASSWORD):
func()
else:
return HttpResponseForbidden("Forbidden")
return process_request
我用它来装饰这样的视图:
@csrf_exempt
@basic_auth
def user_find(request):
args = json.loads(request.body, object_hook=utils._datetime_decoder)
providedEmail = args['providedEmail']
try:
user = User.objects.get(email=providedEmail)
user_dict = {'exists': 'true', 'name': user.first_name, 'email': user.email}
return HttpResponse(json.dumps(user_dict))
except User.DoesNotExist:
user_dict = {'exists': 'false'}
return HttpResponse(json.dumps(user_dict))
出于某种原因,我没有得到我的期望。视图在没有装饰器的情况下完美地工作,但它不会与装饰器一起使用。我收到上面的错误:
process_request() takes exactly 2 arguments (1 given)
你知道这里会发生什么吗?
答案 0 :(得分:1)
您没有将请求作为参数传递给 func()。试试这个:
if (auth_email == settings.BASIC_AUTH_EMAIL) and (auth_password == settings.EMAIL_HOST_PASSWORD):
func(request)
else:
return HttpResponseForbidden("Forbidden")
答案 1 :(得分:1)
从 process_request 中移除self并将请求参数传递给 func()
def basic_auth(func):
def process_request(request):
if request.META.get("HTTP_AUTHORIZATION"):
encoded_auth = request.META.get("HTTP_AUTHORIZATION")
encoded_auth = encoded_auth[6:]
auth = base64.b64decode(encoded_auth)
auth_email = auth.split(":")[0]
auth_password = auth.split(":")[1]
if (auth_email == settings.BASIC_AUTH_EMAIL) and (auth_password == settings.EMAIL_HOST_PASSWORD):
func(request)
else:
return HttpResponseForbidden("Forbidden")
return process_request
为了更好地理解函数装饰器: http://thecodeship.com/patterns/guide-to-python-function-decorators/