Now I made some API with Django rest-framework. And I used JWT for token authentication.
At this moment, I have some questions about token permission.
How can I detect token permission in Django?
For example, There is user A and user B.
When user A wrote article "test", article "test" can only be edited or deleted by user A.
But how can I detect permission about article "test"?
The token will be changed every time when user login. So detect by token is not the correct way.
I searching Google few hours, if there is any solution about this. Is there any way to determine user permission by token?
Thanks in advance!
JWT authentication allows you to identify the user who have previously signed up to your Django app, thanks to the token attached to every request they send to your server.
Then, a permission (that you define and shape as you wish) allows you to let or not let user access / edit a given resource / page.
More practically, what you want to achieve can be set up as follows (assuming you use class based views):
class MyApiEndpoint(ApiView):
authentication_classes = (JSONWebTokenAuthentication,)
permission_classes = (IsOwner,)
where:
JSONWebTokenAuthentication is the authentication class provided by djangorestframework-jwt.
IsOwner is a Permission class you need to write to check if the current user is owner of the resource hosted by the given view / API endpoint. (More on this here).
Related
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.
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,)
i try to build a REST API with Flask-JSONAPI and Flask Security.
I use Auth Token for authentication and #login_required to secure my API Endpints. (Authentication)
But now I want to ensure that only the owner of objects (Creator) can (C)RUD the data. Right now every user can see every object that is created. (Autorisation)
I want to use Resource Manager here but did't find a proper example for Flask Security in Resource Managers.
For Example the user (person) can only see the computer objects associated with the same user id.
Do I have to use the Auth Token for that?
Is there a simple way to get the id of the user logged in, doing the request?
from flask_security import current user
That represents a user instance of the currently logged in user. This user can be anonymous in cases where no user is logged in, but if a user is logged in then the object will represent an object of the User class.
in django drf can a authenticated user with token access other users data?
I know it shouldn't but in my application its not happening.
for testing I was using the token in postman but I was surprised when I see by using one users token I can access any other user data by changing PK in url.
when I researched this on internet I couldn't find any definite answer.
may be I was using the token authentication method wrongfully...
but my main question is:
If I have one users token then by just changing pk in url, should I be able to get other users data? if so how to avoid that?
(Note: I am currently NOT using HTTPS. )
(also this is a conceptual question so after getting answer of this I may need to ask another question regarding error in my code; that I will. but please provide answer to this)
If your view for sending user data has only the permission class isAuthenticated, then yes this behavior is to be expected.
What you need to do is to implement Another permission isOwner that checks if the user asking for the data is its owner or not.
No. if that happened, it means you implement authentication the wrong way.
Make sure you set authentication scheme to 'rest_framework.authentication.TokenAuthentication'
and include 'rest_framework.authtoken' in your INSTALLED_APPS
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/