Using Basic HTTP access authentication in Django testing framework

前端 未结 6 1443
栀梦
栀梦 2020-12-08 01:41

For some of my Django views I\'ve created a decorator that performs Basic HTTP access authentication. However, while writing test cases in Django, it took me a while to wor

相关标签:
6条回答
  • 2020-12-08 02:26

    (python3) I'm using this in a test:

    credentials_string = '%s:%s' % ('invalid', 'invalid')
    credentials = base64.b64encode(credentials_string.encode())
    self.client.defaults['HTTP_AUTHORIZATION'] = 'Basic ' + credentials.decode()
    

    and the following in a view:

    import base64
    [...]
    type, auth = request.META['HTTP_AUTHORIZATION'].split(' ', 1)
    auth = base64.b64decode(auth.strip()).decode()
    
    0 讨论(0)
  • 2020-12-08 02:27

    Here's how I did it:

    from django.test import Client
    import base64
    auth_headers = {
        'HTTP_AUTHORIZATION': 'Basic ' + base64.b64encode('username:password'),
    }
    c = Client()
    response = c.get('/my-protected-url/', **auth_headers)
    

    Note: You will also need to create a user.

    0 讨论(0)
  • 2020-12-08 02:33

    For python3, you can base64-encode your username:password string:

    base64.b64encode(b'username:password')
    

    This returns bytes, so you need to transfer it into an ASCII string with .decode('ascii'):

    Complete example:

    import base64
    
    from django.test import TestCase
    
    class TestClass(TestCase):
       def test_authorized(self):
           headers = {
               'HTTP_AUTHORIZATION': 'Basic ' + 
                    base64.b64encode(b'username:password').decode("ascii")
           }
           response = self.client.get('/', **headers)
           self.assertEqual(response.status_code, 200)
    
    0 讨论(0)
  • 2020-12-08 02:38

    Another way to do it is to bypass the Django Client() and use Requests instead.

    class MyTest(TestCase):
        def setUp(self):
            AUTH = requests.auth.HTTPBasicAuth("username", "password")
    
        def some_test(self):
            resp = requests.get(BASE_URL + 'endpoint/', auth=AUTH)
            self.assertEqual(resp.status_code, 200)
    
    0 讨论(0)
  • 2020-12-08 02:40

    Assuming I have a login form, I use the following technique to login through the test framework:

        client = Client()
        client.post('/login/', {'username': 'john.smith', 'password': 'secret'})
    

    I then carry the client around in my other tests since it's already authenticated. What is your question to this post?

    0 讨论(0)
  • 2020-12-08 02:44

    In your Django TestCase you can update the client defaults to contain your HTTP basic auth credentials.

    import base64
    from django.test import TestCase
    
    class TestMyStuff(TestCase):
    
        def setUp(self):
            credentials = base64.b64encode('username:password')
            self.client.defaults['HTTP_AUTHORIZATION'] = 'Basic ' + credentials
    
    0 讨论(0)
提交回复
热议问题