Add BaseTokenAuthentication base class.

`BaseTokenAuthentication` class extract token-authentication functionality from `TokenAuthentication` class.
Also, new `BaseTokenAuthentication.authenticate_token(request, token)` method allow you implement ip-based authentication tokens.

This is useful base class to use non-model-based tokens in applications.

Change is backward compatible (calls `TokenAuthentication.authenticate_credentials()` method by default).
This commit is contained in:
mixkorshun 2017-07-09 00:55:28 +03:00
parent 3dab905656
commit 27f69dc23a

View File

@ -140,9 +140,9 @@ class SessionAuthentication(BaseAuthentication):
raise exceptions.PermissionDenied('CSRF Failed: %s' % reason) raise exceptions.PermissionDenied('CSRF Failed: %s' % reason)
class TokenAuthentication(BaseAuthentication): class BaseTokenAuthentication(BaseAuthentication):
""" """
Simple token based authentication. Token based authentication base class.
Clients should authenticate by passing the token key in the "Authorization" Clients should authenticate by passing the token key in the "Authorization"
HTTP header, prepended with the string "Token ". For example: HTTP header, prepended with the string "Token ". For example:
@ -151,20 +151,6 @@ class TokenAuthentication(BaseAuthentication):
""" """
keyword = 'Token' keyword = 'Token'
model = None
def get_model(self):
if self.model is not None:
return self.model
from rest_framework.authtoken.models import Token
return Token
"""
A custom token model may be used, but must have the following properties.
* key -- The string identifying the token
* user -- The user to which the token belongs
"""
def authenticate(self, request): def authenticate(self, request):
auth = get_authorization_header(request).split() auth = get_authorization_header(request).split()
@ -185,6 +171,38 @@ class TokenAuthentication(BaseAuthentication):
msg = _('Invalid token header. Token string should not contain invalid characters.') msg = _('Invalid token header. Token string should not contain invalid characters.')
raise exceptions.AuthenticationFailed(msg) raise exceptions.AuthenticationFailed(msg)
return self.authenticate_token(request, token)
def authenticate_token(self, request, token):
raise NotImplementedError("`authenticate_token` method must be impemented.")
def authenticate_header(self, request):
return self.keyword
class TokenAuthentication(BaseTokenAuthentication):
"""
Simple token based authentication.
Use token stored in database.
"""
model = None
def get_model(self):
if self.model is not None:
return self.model
from rest_framework.authtoken.models import Token
return Token
"""
A custom token model may be used, but must have the following properties.
* key -- The string identifying the token
* user -- The user to which the token belongs
"""
def authenticate_token(self, request, token):
return self.authenticate_credentials(token) return self.authenticate_credentials(token)
def authenticate_credentials(self, key): def authenticate_credentials(self, key):
@ -198,6 +216,3 @@ class TokenAuthentication(BaseAuthentication):
raise exceptions.AuthenticationFailed(_('User inactive or deleted.')) raise exceptions.AuthenticationFailed(_('User inactive or deleted.'))
return (token.user, token) return (token.user, token)
def authenticate_header(self, request):
return self.keyword