Django: Basic Auth for one view (avoid middleware)

前端 未结 4 1167
星月不相逢
星月不相逢 2021-02-18 23:46

I need to provide http-basic-auth to one view.

I want to avoid modifying the middleware settings.

Background: This is a view which gets fil

4条回答
  •  不思量自难忘°
    2021-02-19 00:00

    When you do a basic auth request, you're really adding credentials into the Authorization header. Before transit, these credentials are base64-encoded, so you need to decode them on receipt.

    The following code snippet presumes that there's only one valid username and password:

    import base64
    
    def my_view(request):
        auth_header = request.META.get('HTTP_AUTHORIZATION', '')
        token_type, _, credentials = auth_header.partition(' ')
    
        expected = base64.b64encode(b'username:password').decode()
    
        if token_type != 'Basic' or credentials != expected:
            return HttpResponse(status=401)
    
        # Your authenticated code here:
        ...
    

    If you wish to compare to the username and password of a User model, try the following instead:

    def my_view(request):
        auth_header = request.META.get('HTTP_AUTHORIZATION', '')
        token_type, _, credentials = auth_header.partition(' ')
    
        username, password = base64.b64decode(credentials).split(':')
        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            return HttpResponse(status=401)
    
        password_valid = user.check_password(password)
    
        if token_type != 'Basic' or not password_valid:
            return HttpResponse(status=401)
    
        # Your authenticated code here:
        ...
    

    Please note that this latter version is not extremely secure. At first glance, I can see that it is vulnerable to timing attacks, for example.

提交回复
热议问题