Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

oAuth authentication in unit tests using django rest framework and django oauth toolkit

How do I write unit tests for those endpoints of my API that require oAuth authentication?

Simply adding oAuth tokens to the request headers doesn't work (perhaps because the test database is not persistent). Loading fixtures into the database doesn't help either.

I am using django-rest-framework together with django-oauth-toolkit.

My test.py code:

class Com_jm_Test(TestCase):
    fixtures=['oauth.json',]
    print 'test com jm'
    multi_db=True

    def test_list_job(self):
        self.client=Client(HTTP_AUTHORIZATION='Bearer 0cx2G9gKm4XZdK8BFxoWy7AE025tvq')
        response=self.client.get('/com-jm/jobs/')
        self.assertEqual(response.status_code,200)

The result:

AssertionError: 401 != 200
like image 533
JadenGuo Avatar asked May 13 '15 07:05

JadenGuo


People also ask

What is OAuth authentication in Django?

Open Authorization (OAuth) is a service that allows websites or apps to share user information with other websites without being given a users password. Users can log in to multiple websites with the same account without creating other credentials.

Does Django use OAuth2?

Django OAuth Toolkit can help you by providing, out of the box, all the endpoints, data, and logic needed to add OAuth2 capabilities to your Django projects. Django OAuth Toolkit makes extensive use of the excellent OAuthLib, so that everything is rfc-compliant.


2 Answers

Do it this way:

  1. Create user
  2. Create application
  3. Create token

    def __create_authorization_header(token):
        return "Bearer {0}".format(token)
    
    def __create_token(self, user):
    
        app = Application.objects.create(
            client_type=Application.CLIENT_CONFIDENTIAL,
            authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE,
            redirect_uris='https://www.none.com/oauth2/callback',
            name='dummy',
            user=user
        )
        access_token = AccessToken.objects.create(
            user=user,
            scope='read write',
            expires=timezone.now() + timedelta(seconds=300),
            token='secret-access-token-key',
            application=self.app
        )
        return access_token
    
     user = User(username='dummy', email='[email protected]')
     user.save()
     self.user = user
     token = __create_authorization_header(__create_token(user))
     response=self.client.get('/com-jm/jobs/', format='json', HTTP_AUTHORIZATION=token)
    

    self.assertEqual(response.status_code,200)

Off-course this must be adapt to your needs, but this is the idea. For future problems of this kind (when you didn't find enough information in the documentation for archive your goals) i recommend you to check out the source code. In this case for example you can find how to do this in the test of the toolkit lib. (django-oauth-toolkit/oauth2_provider/tests/test_authorization_code.py)

like image 131
Daniel Albarral Avatar answered Nov 10 '22 14:11

Daniel Albarral


I was facing the same problem. Here is my solution.

DRF provides APIClient for making requests.

The APIClient class supports the same request interface as Django's standard Client class. This means that the standard .get(), .post(), .put(), .patch(), .delete(), .head() and .options() methods are all available.

Also provides The credentials method can be used to set headers that will then be included on all subsequent requests by the test client.

client = APIClient()
client.credentials(HTTP_AUTHORIZATION='Token AB7JSH^4454')

DRF docs

Creating Oauth Token

create and get user

token = user.oauth2_provider_accesstoken.create(expires='expire_date', token='token')

Setting Ouath token with APIClient

client = APIClient()
client.credentials(Authorization='Bearer {}'.format(token))
client.get(reverse('accounts_api:profile'))

We can set the Default content type

REST_FRAMEWORK += {
    'TEST_REQUEST_DEFAULT_FORMAT': 'json'
}

Git Hub Link for Source

like image 29
Deepak Kabbur Avatar answered Nov 10 '22 12:11

Deepak Kabbur