Django TokenAuthentication missing the 'Authorization' http header

◇◆丶佛笑我妖孽 提交于 2019-12-21 03:28:08

问题


I'm trying to use the TokenAuthentication with one of my views. As documented in https://www.django-rest-framework.org/api-guide/authentication/, I add the token I received from the login as an HTTP header called: 'Authorization' in the request I send.

The problem is that in my unittests the authentication fails. Looking into the TokenAuthentication class I see that the header being checked is 'HTTP_AUTHORIZATION' and not 'Authorization'

The view I'm using:

class DeviceCreate(generics.CreateAPIView):
    model = Device
    serializer_class = DeviceSerializer

    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

Changing the header to 'HTTP_AUTHORIZATION' seems to work, but something feels wrong.

Am I missing anything?


回答1:


Looking into the TokenAuthentication class I see that the header being checked is 'HTTP_AUTHORIZATION' and not 'Authorization'

Not quite true, when doing lookups in the request META dict, the headers that it's actually looking for are with out the preceeding HTTP_, so request.META.get('HTTP_AUTHORIZATION', '') is actually looking up the Authorization header in the request.

The problem is that in my unittests the authentication fails Changing the header to 'HTTP_AUTHORIZATION' seems to work

I havn't double checked how the test client looks but I believe that setting HTTP_AUTHORIZATION is what you need to do get the equivalent of actually setting the Authorization header. If you actually made an http request you should find that setting the auth header works exactly as you'd expect.

See request.META documentation here: https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META

Edit:

Django docs on looking up headers in request.META:

With the exception of CONTENT_LENGTH and CONTENT_TYPE, as given above, any HTTP headers in the request are converted to META keys by converting all characters to uppercase, replacing any hyphens with underscores and adding an HTTP_ prefix to the name. So, for example, a header called X-Bender would be mapped to the META key HTTP_X_BENDER.

Django docs on setting headers with the test client:

However, you can use keywords arguments to specify some default headers. For example, this will send a User-Agent HTTP header in each request:

c = Client(HTTP_USER_AGENT='Mozilla/5.0')




回答2:


Tom's answer is fine, but not complete.

Your code can work fine in dev environnement (with runserver) but if you try it in a WSGI server (Apache in my case), the server can strip out the Authorization header !

You can find on Boone's Blog a good fix for your Apache conf to keep the Authorization header in the request and make it work great:

RewriteEngine on
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]


来源:https://stackoverflow.com/questions/15113248/django-tokenauthentication-missing-the-authorization-http-header

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!