Commit f741cdae by Mjumbe Wawatu Poe

Move TokenAuthentication class into djangorestframework.authentication

parent 10450baf
...@@ -103,4 +103,38 @@ class SessionAuthentication(BaseAuthentication): ...@@ -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
...@@ -9,7 +9,7 @@ from djangorestframework.views import APIView ...@@ -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): ...@@ -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)
......
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)
...@@ -67,9 +67,9 @@ If successfully authenticated, `UserBasicAuthentication` provides the following ...@@ -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 ...@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment