TokenAuthentication: Allow custom keyword in the header by hroncok · Pull Request #4097 · encode/django-rest-framework (original) (raw)

I don't understand the objection against this, so I'll try to explain my reason even further.

This is the customization I would like to be able to do (In my own code/project/app) and this pull request makes that possible:

from rest_framework import authentication

class BearerAuthentication(authentication.TokenAuthentication): ''' Simple token based authentication using utvsapitoken.

Clients should authenticate by passing the token key in the 'Authorization'
HTTP header, prepended with the string 'Bearer '.  For example:

    Authorization: Bearer 956e252a-513c-48c5-92dd-bfddc364e812
'''
keyword = 'Bearer'

Unfortunately, this is what has to be done at this point (without this pull request):

from rest_framework import authentication, exceptions from django.utils.translation import ugettext_lazy as _

class BearerAuthentication(authentication.TokenAuthentication): ''' Simple token based authentication using utvsapitoken.

Clients should authenticate by passing the token key in the 'Authorization'
HTTP header, prepended with the string 'Bearer '.  For example:

    Authorization: Bearer 956e252a-513c-48c5-92dd-bfddc364e812
'''
def authenticate(self, request):
    auth = authentication.get_authorization_header(request).split()

    if not auth or auth[0].lower() != b'bearer':
        return None

    if len(auth) == 1:
        msg = _('Invalid token header. No credentials provided.')
        raise exceptions.AuthenticationFailed(msg)
    elif len(auth) > 2:
        msg = _('Invalid token header. Token string should not contain spaces.')
        raise exceptions.AuthenticationFailed(msg)

    try:
        token = auth[1].decode()
    except UnicodeError:
        msg = _('Invalid token header. Token string should not contain invalid characters.')
        raise exceptions.AuthenticationFailed(msg)

    return self.authenticate_credentials(token)

def authenticate_header(self, request):
    return 'Bearer'

This is no customization, this is copy pasting code form Django REST framework.
This has many disadvantages, every time the code is changed in DRF (let's say for security fixes etc.), I would need to keep tack of such change and change my copy pasted code.

This PR simply allows easier customization. Would you please reconsider, or provide more verbose explanation? I'm willing to shape this PR a bit (make keyword a method, rename it, etc.). Thanks