How can I use JWT tokens in Django Rest Framework? - django

I'm new to django and DRF, I'm trying to build an authentification system using JWT, I want to login the user directly after registering, I read the documentation and I managed to create a token manually and return it in my serializer, but my questions are this:
1) How can I use this token to see if the user is logged in or not?
2) Can I use the {% if user.is_authenticated %} in my templates? if so how?
3) How can I get the user logged in informations in another view?
4) Is there a more efficient way of dealing with authentifications with DRF?

1- Basically when you are using DRF and jwt token, Means you are using token-based authentication, So all your requests should contains a http header for Authorization: basic <token value>. So django drf authentication backend, will recognize this token and if valid, user will be authenticated.
2- I don't think you can use that templatetag anymore. Because that's for session based authentications.
3- if you provide the authentication backed for that token and send the token in header, every view should has user info in request.user
4- One of the best solutions in my opinion is token-based with jwt tokens.

DRF Auth and Permissions has a lot of useful information on working with auth and permissions in DRF, check it out.
Adding on to what #Reza-Torkaman-Ahmadi said:
In your views you can use permissions to make sure a user is authenticated:
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

Related

Are Django's auth backend and DRF's token authentication just two approaches to the same thing?

In my django web app, which is split into a front and and a back end project, I am currently using a custom AuthBackend class that extends django's BaseBackend, as well as DRF's UserTokenAuthentication.
Am I right to think that I only need one of these approaches? Or is there a reason to use django's login() function, even if i am using DRF's token auth? I know it stores the user in the session, so I guess that would make passing and authenticating a token pointless?
What's my best approach? Cheers :)
There are differences in both namespaces wise and purpose wise.
In Django, auth backends handle session-based authentication only whereas rest framework auth supports not only session-based auth but also token (JWT, OAuth ), and basic auth based authentication.
Besides, Django auth backends authenticate requests during passing through middle-ware and rest framework authenticate without middle-ware.
If you are planning to separate your backend and frontend then go for token-based auth. There is no reason to use the login function of Django if you only use token-based auth to authenticate.

Django Rest Framework JWT user register/login concept

I'm creating a Login/Register API with Django Rest Framework which is consumed by my frontend, using JWT to authenticate and there are some basic things I can't seem to understand and maybe someone can help me out.
I created an endpoint to register a user (a POST to /users/). At first I was getting a "Authentication credentials were not provided." if I tried sending a request using Postman (on Django API GUI it would work normally I guess because they already send the correct authentication). However, when I think about it, it comes to me that he doesn't have the credentials yet since he's not registered and logged in, so its JWT wasn't created, so I added permission_classes = (AllowAny, ) to my APIView. But then it allows anyone to use the API, therefore anyone would be able to send a PATCH request to update some info without sending the JWT in the request. Anyone have any idea on how to handle that?
I think somehow I'm lacking some kind of concept about authentication. Maybe I need one exclusively for communicating my backend and frontend that will be used to register a user and the users JWT will be used to perform the other actions?
If needed, I can provide other informations about my architecture or code.
First As per your description,
I created an endpoint to register a user (a POST to /users/). At first I was getting a "Authentication credentials were not provided." if I tried sending a request using Postman (on Django API GUI it would work normally I guess because they already send the correct authentication).
You have to understand that since the api is a user registraion api, the permission class should always be set as permission_class = (AllowAny,), but you set permission_class = (IsAuthenticated,) in your view, so django expecting a proper authentication credential(a JWT token as you are using JWT) to make sure the requested user is authenticated. Thats why you are getting a "Authentication credentials were not provided." exception in your POST /users/ api.
Second, as you said later,
However, when I think about it, it comes to me that he doesn't have the credentials yet since he's not registered and logged in, so its JWT wasn't created, so I added permission_classes = (AllowAny, ) to my APIView
its obvious when a user registering himself/herself, then he/she will not have any credentials(JWT token).
then you said,
But then it allows anyone to use the API, therefore anyone would be able to send a PATCH request to update some info without sending the JWT in the request.
From these lines it seems that you are using single api view to Create(POST) and partial update(PATCH) of user. What you have to do is to make separate api views. That is one api view for Create/Register(POST) user and set permission_classes = (AllowAny, ) and another api view to Update(PATCH) user and set permission_class = (IsAuthenticated,). I think this will solve your problem.
EDITION: Now for better understanding how permission works in django rest framework, lets check this the way permission works in django rest framework.

How to make REST api calls that needs auth_token?

I'm working on a Django-REST application that contains APIs that work with login mechanism.
I'm able to create API endpoints for login and logouts.
Login takes username, password and returns auth_token which is around 30 characters.
Logout takes auth_token and destroys it.
In between these login and logouts, there are few API calls that make use of auth_token.
How is it generally implemented ? How are the requests made with auth_token in general?
Where are those tokens stored? How do the backend validates it?
Can someone please explain me how it is done basically?
store the token in browser storage. and remove the token form browser storage on logout logic.
make sure you drf setting DEFAULT_AUTHENTICATION_CLASSES list contain TokenAuthentication class before SessionAuthentication , rest_framework.authtoken in you setting install app.
for any api call just attach the token like (Token your_toke) I mean "Toke" then space the your token and attach it to your request authentication header of the ajax request

Using Firebase Auth with Django

I want to use firebase authentication for my django webapp. To achieve this, I think would I need to write a custom auth backend - is that right? I don't see any libraries that already do this - django-allauth looks like it comes pretty close as an alternative but I am interested in the phone number verification provided by firebase.
I'm also confused about what happens to the User model and functions like request.user or user.is_authenticated. Right now I use the authenticate and login functions - how does django know that a user is logged in via firebase? Would I still be creating a User model for every user?
Thanks
You can use Firebase Auth with any framework. You don't necessarily need to use custom auth. Typically, you would sign in the user on the client, get the ID token by calling firebase.auth().currentUser.getIdToken() and then pass the ID token to your server, verify it and parse its payload identifying the user ID and its other claims by using the Firebase Admin SDKs and then you can issue a session cookie identifying the user associated with that ID token.
On signout, you would clear that session cookie.
If you also need to persist that user on the backend after setting the session cookie, you can also use the Firebase Admin SDK to lookup a user identified by the user ID or just use the token claims to populate the user without any network call. You can populate that in the user model of associated framework if needed.
For more on session management, you can refer to this django documentation: https://docs.djangoproject.com/en/3.0/topics/http/sessions/

Are there authentication examples with Django and Tastypie?

Are there basic authentication examples with Django and Tastypie?. I'm a little bit confused about how the authentication in Django works, specially with Tastypie.I wanna know how the authentication works with api keys and how to authenticate a user with the built-in User model which Django has. Any suggestion or code are really appreciated.
Thanks.
Just to answer your questions regarding authentication:
How the authentication in Django works?
Django authentication required SessionMiddleware to work. Once a session has been loaded, the Django authentication backend reads a special cookie _auth_user (IIRC) which contains currently logged in user's ID. If you have access to the django shell, you can manipulate it and make yourself logged in as any user! Once the backend notices there is a _auth_user key, it then adds a lazy User object to the request (so it delays the User.objects.get(...) until it is really needed). If there is no such key in the session dict, the user is claimed to be anonymous and an instance of AnonymousUser is added to the request object instead.
How does the authentication work in Tastypie?
Before your resource view is executed, a Resource.is_authenticated(request) method is called, which in turn calls the is_authenticated(request) method of the authentication backend of your the Resource of your choice. If the method returns False, the authentication is claimed to be failed and returns with Unauthorized error. If the method returns a HttpResponse, the response is returned instead. If the method returns True, the request is claimed to have been authenticated.
How does User model authentication work in Tastypie?
The User model authentication can be performed using SessionAuthentication backend provided by the Tastypie itself. What it does is creating a session for the current request so that the authentication middleware can then automatically insert relevant user model to the request. Notice that for this method to work, your API client has to support storing cookies and resending them in future requests.
You might find this useful. It allows you to authenticate the user based on the Django session cookie.
https://github.com/amezcua/TastyPie-DjangoCookie-Auth/blob/master/DjangoCookieAuth.py
I am using this in my application and it works!