Django: Rest Framework authenticate header

2019-01-30 04:41发布

问题:

Using Django REST API, I'm trying to authenticate my request.

This is what I'm trying to send:

Content-Type: application/json, Authentication: token="6d82549b48a8b079f618ee9c51a6dfb59c7e2196"

This is what I get back:

{"detail": "Authentication credentials were not provided."}

Could someone give me the correct header?

Thanks

The Header:

Accept: application/json
Content-Type: application/json
Authorization: Token 6d82549b48a8b079f618ee9c51a6dfb59c7e2196
Connection: keep-alive
Origin: chrome-extension: //rest-console-id
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17

Settings.py

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.permissions.IsAdminUser',


    ),
    'PAGINATE_BY': 10
}

view.py

class ProfileList(generics.ListCreateAPIView):
    """
    API endpoint that represents a list of users.
    """
    permission_classes = (permissions.IsAuthenticated,)
    model = Profile
    serializer_class = ProfileSerializer

    def pre_save(self, obj):
        obj.owner = self.request.user

回答1:

Assuming you're trying to use TokenAuthentication, the header should look like this:

Authorization: Token 6d82549b48a8b079f618ee9c51a6dfb59c7e2196

As described in the documentation.



回答2:

Just in case anyone else comes across this error. This can also happen if you are running Django on Apache using mod_wsgi because the authorization header is stripped out by mod_wsgi. You'll need to add the following to your VirtualHost configuration:

WSGIPassAuthorization On



回答3:

I was having the same trouble with my Token Authentication

This fixed the problem to me

settings.py

REST_FRAMEWORK = {
   'DEFAULT_AUTHENTICATION_CLASSES': (
       'rest_framework.authentication.TokenAuthentication',
   ),
   'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAdminUser'
   ),
   'PAGINATE_BY': 10,
}


回答4:

In my case this works:
(Django REST Framework v3)

settings.py

REST_FRAMEWORK = {
   'DEFAULT_AUTHENTICATION_CLASSES': (
       'rest_framework.authentication.TokenAuthentication',
       'rest_framework.authentication.SessionAuthentication',
   ),
   'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
   ),
}

views.py

class Test(APIView):
    def get(self, request, format=None):   
        return Response({'Result': 'OK'})

urls.py

router.add_api_view('test', url(r'^test/', views.Test.as_view(),name='test'))

Don't forget to send the token information in the header:

 Key: Authorization  
 Value: Token 76efd80cd6849ad7d35e04f1cc1eea35bdc20294

To generate tokens you can use the following (somewhere in your code):

from rest_framework.authtoken.models import Token            
user = User.objects.get(username='<username>')
token = Token.objects.create(user=user)
print(token.key)


回答5:

For those who are on AWS elastic beanstalk and you are kind of stuck with apache and unless you have

WSGIPassAuthorization On

As mentioned by @Fiver your headers get stripped

Instead of manually fixing this and making a new image, I made a script that checks if the last line of the conf file is WSGIPassAuthorization On and if it is not we update it and restart the server

In my Django app I have a config folder with my sh file

configs/server/update-apache.sh

if [[ $(tac /etc/httpd/conf/httpd.conf | egrep -m 1 .) == $(echo 'WSGIPassAuthorization On') ]];
  then
     echo "Httpd.conf has already been updated"
  else
     echo "Updating Httpd.conf.."
     echo 'WSGIPassAuthorization On' >> /etc/httpd/conf/httpd.conf
     service httpd restart
fi

Make it excecutable before I commit it to git

chmod +x configs/server/update-apache.sh

Then in my python.config file I add the command at the end

.ebextensions/python.config

...
...
container_commands:
    01_migrate:
        command: "python manage.py migrate"
        leader_only: true
    02_collectstatic:
        command: "python manage.py collectstatic --noinput"
    03_change_perm:
        command: "chown -R wsgi:root static"
    03_update_apache:
        command: "sh configs/server/update-apache.sh"

Now any new machine that starts up will have a check done to see if the server is updated and does so if need be