Move TokenAuthentication class into djangorestframework.authentication

This commit is contained in:
Mjumbe Wawatu Poe 2012-09-07 16:12:33 -04:00
parent 10450bafc9
commit f741cdae44
4 changed files with 41 additions and 43 deletions

View File

@ -103,4 +103,38 @@ class SessionAuthentication(BaseAuthentication):
return (user, None) return (user, None)
# TODO: TokenAuthentication, DigestAuthentication, OAuthAuthentication class TokenAuthentication(BaseAuthentication):
"""
Use a token model for authentication.
A custom token model may be used here, but must have the following minimum
properties:
* key -- The string identifying the token
* user -- The user to which the token belongs
* revoked -- The status of the token
The token key should be passed in as a string to the "Authorization" HTTP
header. For example:
Authorization: 0123456789abcdef0123456789abcdef
"""
model = None
def authenticate(self, request):
key = request.META.get('HTTP_AUTHORIZATION', '').strip()
if self.model is None:
from djangorestframework.tokenauth.models import BasicToken
self.model = BasicToken
try:
token = self.model.objects.get(key=key)
except self.model.DoesNotExist:
return None
if token.user.is_active and not token.revoked:
return (token.user, token)
# TODO: DigestAuthentication, OAuthAuthentication

View File

@ -9,7 +9,7 @@ from djangorestframework.views import APIView
from djangorestframework import permissions from djangorestframework import permissions
from djangorestframework.tokenauth.models import BasicToken from djangorestframework.tokenauth.models import BasicToken
from djangorestframework.tokenauth.authentication import TokenAuthentication from djangorestframework.authentication import TokenAuthentication
import base64 import base64
@ -127,13 +127,13 @@ class TokenAuthTests(TestCase):
def test_post_form_passing_token_auth(self): def test_post_form_passing_token_auth(self):
"""Ensure POSTing json over token auth with correct credentials passes and does not require CSRF""" """Ensure POSTing json over token auth with correct credentials passes and does not require CSRF"""
auth = 'Token %s' % self.key auth = self.key
response = self.csrf_client.post('/', {'example': 'example'}, HTTP_AUTHORIZATION=auth) response = self.csrf_client.post('/', {'example': 'example'}, HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
def test_post_json_passing_token_auth(self): def test_post_json_passing_token_auth(self):
"""Ensure POSTing form over token auth with correct credentials passes and does not require CSRF""" """Ensure POSTing form over token auth with correct credentials passes and does not require CSRF"""
auth = 'Token %s' % self.key auth = self.key
response = self.csrf_client.post('/', json.dumps({'example': 'example'}), 'application/json', HTTP_AUTHORIZATION=auth) response = self.csrf_client.post('/', json.dumps({'example': 'example'}), 'application/json', HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)

View File

@ -1,36 +0,0 @@
from djangorestframework.authentication import BaseAuthentication
from .models import BasicToken
class TokenAuthentication(BaseAuthentication):
"""
Use a token model for authentication.
A custom token model may be used here, but must have the following minimum
properties:
* key -- The string identifying the token
* user -- The user to which the token belongs
* revoked -- The status of the token
The BaseToken class is available as an abstract model to be derived from.
The token key should be passed in as a string to the "Authorization" HTTP
header. For example:
Authorization: Token 0123456789abcdef0123456789abcdef
"""
model = BasicToken
def authenticate(self, request):
auth = request.META.get('HTTP_AUTHORIZATION', '').strip().split()
if len(auth) == 2 and auth[0].lower() == "token":
key = auth[1]
try:
token = self.model.objects.get(key=key)
except self.model.DoesNotExist:
return None
if token.user.is_active and not token.revoked:
return (token.user, token)

View File

@ -67,9 +67,9 @@ If successfully authenticated, `UserBasicAuthentication` provides the following
## TokenAuthentication ## TokenAuthentication
This policy uses [HTTP Authentication][basicauth] with a custom authentication scheme called "Token". Token basic authentication is appropriate for client-server setups, such as native desktop and mobile clients. The token key should be passed in as a string to the "Authorization" HTTP header. For example: This policy uses [HTTP Authentication][basicauth] with no authentication scheme. Token basic authentication is appropriate for client-server setups, such as native desktop and mobile clients. The token key should be passed in as a string to the "Authorization" HTTP header. For example:
curl http://my.api.org/ -X POST -H "Authorization: Token 0123456789abcdef0123456789abcdef" curl http://my.api.org/ -X POST -H "Authorization: 0123456789abcdef0123456789abcdef"
**Note:** If you run `TokenAuthentication` in production your API must be `https` only, or it will be completely insecure. **Note:** If you run `TokenAuthentication` in production your API must be `https` only, or it will be completely insecure.
@ -78,7 +78,7 @@ If successfully authenticated, `TokenAuthentication` provides the following cred
* `request.user` will be a `django.contrib.auth.models.User` instance. * `request.user` will be a `django.contrib.auth.models.User` instance.
* `request.auth` will be a `djangorestframework.tokenauth.models.BasicToken` instance. * `request.auth` will be a `djangorestframework.tokenauth.models.BasicToken` instance.
To use the `TokenAuthentication` scheme, you must have a token model. Django REST Framework comes with a minimal default token model. To use it, include `djangorestframework.tokenauth` in your installed applications. To use your own token model, subclass the `djangorestframework.tokenauth.authentication.TokenAuthentication` class and specify a `model` attribute that references your custom token model. The token model must provide `user`, `key`, and `revoked` attributes. For convenience, the `djangorestframework.tokenauth.models.BaseToken` abstract model implements this minimum contract, and also randomly populates the key field when none is provided. To use the `TokenAuthentication` policy, you must have a token model. Django REST Framework comes with a minimal default token model. To use it, include `djangorestframework.tokenauth` in your installed applications and sync your database. To use your own token model, subclass the `djangorestframework.tokenauth.TokenAuthentication` class and specify a `model` attribute that references your custom token model. The token model must provide `user`, `key`, and `revoked` attributes. For convenience, the `djangorestframework.tokenauth.models.BaseToken` abstract model implements this minimum contract, and also randomly populates the key field when none is provided.
## OAuthAuthentication ## OAuthAuthentication