mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-23 10:03:57 +03:00
Add a TokenAuthentication class in a sub-application
This commit is contained in:
parent
72bdd0fcec
commit
f3e65eab6b
|
@ -90,6 +90,7 @@ INSTALLED_APPS = (
|
|||
# Uncomment the next line to enable admin documentation:
|
||||
# 'django.contrib.admindocs',
|
||||
'djangorestframework',
|
||||
'djangorestframework.tokenauth',
|
||||
)
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
|
|
|
@ -8,6 +8,9 @@ from django.http import HttpResponse
|
|||
from djangorestframework.views import APIView
|
||||
from djangorestframework import permissions
|
||||
|
||||
from djangorestframework.tokenauth.models import Token
|
||||
from djangorestframework.tokenauth.authentication import TokenAuthentication
|
||||
|
||||
import base64
|
||||
|
||||
|
||||
|
@ -20,6 +23,8 @@ class MockView(APIView):
|
|||
def put(self, request):
|
||||
return HttpResponse({'a': 1, 'b': 2, 'c': 3})
|
||||
|
||||
MockView.authentication += (TokenAuthentication,)
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^$', MockView.as_view()),
|
||||
)
|
||||
|
@ -104,3 +109,40 @@ class SessionAuthTests(TestCase):
|
|||
"""
|
||||
response = self.csrf_client.post('/', {'example': 'example'})
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
|
||||
class TokenAuthTests(TestCase):
|
||||
"""Token authentication"""
|
||||
urls = 'djangorestframework.tests.authentication'
|
||||
|
||||
def setUp(self):
|
||||
self.csrf_client = Client(enforce_csrf_checks=True)
|
||||
self.username = 'john'
|
||||
self.email = 'lennon@thebeatles.com'
|
||||
self.password = 'password'
|
||||
self.user = User.objects.create_user(self.username, self.email, self.password)
|
||||
|
||||
self.key = 'abcd1234'
|
||||
self.token = Token.objects.create(key=self.key, user=self.user)
|
||||
|
||||
def test_post_form_passing_token_auth(self):
|
||||
"""Ensure POSTing json over token auth with correct credentials passes and does not require CSRF"""
|
||||
auth = self.key
|
||||
response = self.csrf_client.post('/', {'example': 'example'}, HTTP_AUTHORIZATION=auth)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_post_json_passing_token_auth(self):
|
||||
"""Ensure POSTing form over token auth with correct credentials passes and does not require CSRF"""
|
||||
auth = self.key
|
||||
response = self.csrf_client.post('/', json.dumps({'example': 'example'}), 'application/json', HTTP_AUTHORIZATION=auth)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_post_form_failing_token_auth(self):
|
||||
"""Ensure POSTing form over token auth without correct credentials fails"""
|
||||
response = self.csrf_client.post('/', {'example': 'example'})
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_post_json_failing_token_auth(self):
|
||||
"""Ensure POSTing json over token auth without correct credentials fails"""
|
||||
response = self.csrf_client.post('/', json.dumps({'example': 'example'}), 'application/json')
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
|
0
djangorestframework/tokenauth/__init__.py
Normal file
0
djangorestframework/tokenauth/__init__.py
Normal file
33
djangorestframework/tokenauth/authentication.py
Normal file
33
djangorestframework/tokenauth/authentication.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
from djangorestframework.authentication import BaseAuthentication
|
||||
from .models import Token
|
||||
|
||||
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.
|
||||
"""
|
||||
model = Token
|
||||
|
||||
def authenticate(self, request):
|
||||
key = request.META.get('HTTP_AUTHORIZATION', '').strip()
|
||||
if not key:
|
||||
return None
|
||||
|
||||
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)
|
19
djangorestframework/tokenauth/models.py
Normal file
19
djangorestframework/tokenauth/models.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
from django.db import models
|
||||
|
||||
class BaseToken(models.Model):
|
||||
"""
|
||||
The base abstract authorization token model class.
|
||||
"""
|
||||
key = models.CharField(max_length=32, primary_key=True)
|
||||
user = models.ForeignKey('auth.User')
|
||||
revoked = models.BooleanField(default=False)
|
||||
|
||||
class Meta:
|
||||
abstract=True
|
||||
|
||||
|
||||
class Token(BaseToken):
|
||||
"""
|
||||
The default authorization token model class.
|
||||
"""
|
||||
pass
|
Loading…
Reference in New Issue
Block a user