merry-go-round
merry-go-round

Reputation: 4625

How does Django RESTful Framework get user model from token from HTTP header?

I'm building my Django RESTful Framework to retrieve and post data for Mobile. I'm using Django-rest-auth (which is just all-auth with RESTful functionality; more info : http://django-rest-auth.readthedocs.io/en/latest/).

How does Django RESTful Framework (or Django) finds user's model when mobile sends user's token in HTTP header?

For instance:

HTTP METHOD: POST
headers : Authorization eyl3of9iskjfpjowpefjsopeff (This is token and random string) 
body : {
    post_title: "This is my first post"
    post_content: "This is the content" 
}

This is my setting:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.AllowAny',
        # 'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        # 'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ),
}

This is where I want to find a user model :

class CreatePost(generics.CreateAPIView):
    def get_queryset(self, **kwargs):
        owner = User.objects.filter(user= ##) # right here!
        post_title =
        post_content = 

Or any other approach suggested?

Upvotes: 1

Views: 855

Answers (1)

wencakisa
wencakisa

Reputation: 5968

Usually, your Token is simply a Django model, which is stored in your database.

It has a OneToOne relation to your User model and that's simply how they are related (in rest_framework.authtoken). You can see it in DRF source.

A direct examle:

from rest_framework import generics
from rest_framework import status
from rest_framework.authtoken.models import Token
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# You can directly import your Token model for usage

from .serializers import UserLoginSerializer


class UserLogin(generics.CreateAPIView):
    serializer_class = UserLoginSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)

        user = serializer.validated_data['user']
        token, _ = Token.objects.get_or_create(user=user)
        # Here you either get a Token if it exists in your db
        # Or generate it if it is not created yet

        # See that you directly get the token with your user:
        # Token.objects.get_or_create(user=user)

        # You can also access it vice-versa: token.user <-> user.token
        # Because it is a OneToOne relation

        response_data = {
            'id': user.id,
            'token': token.key
        }

        headers = self.get_success_headers(serializer.data)

        return Response(response_data, status=status.HTTP_200_OK, headers=headers)

Note: If you are using JWT, have a look at how a token is linked with the user.

In your case:

class CreatePost(generics.CreateAPIView):
    def get_queryset(self, **kwargs):
        owner = self.request.user
        # Are you sure you don't want to get the current request user?
        # Why you should filter with token?

        post_title = ...
        post_content = ...

Your authentication classes (in your case, JSONWebTokenAuthentication, it automatically sets request.user to the correct one and you can access it in your views).

Upvotes: 2

Related Questions