Creating a user using Djoser authentication is returning a 405 Method Not Allowed Error - django

I am using django and djoser for authentication. By testing the creation of the user using Postman at http://localhost:8000/auth/users using POST method, I am receiving a 405 Method Not Allowed Error.
I am using an SQLite Database and already created a custom user model to use with Djoser:
I already added an X-CSRFToken key and it's secret key in the Headers of the request,and made sure that the method is POST.

Related

In django-simple-jwt package, how can I conditionally validate a password against different signing algorithms & secret keys?

My use-case is that I have a legacy backend that has generated tokens using an insecure secret key. I have imported all the user data into a new backend using simple-jwt. The app owner does not want to force existing users to logout and login again to get a new token.
The problem is when an existing user requests a token, their old password cannot be checked because the existing hash because it was created with the secret key from the old backend. So I would like DRF/simple-jwt to first try to validate against the default key/algorithm, and if that fails attempt against the old, insecure secret key/algorithm.
Is this possible? Do I create a new serializer class based on TokenObtainPair and override validate? If so, how exactly would I do this?
Just add the backend to your authentication backend in your Django settings:
AUTHENTICATION_BACKENDS = [
'path.to.first.auth.backend',
'path.to.second.auth.backend',
]
In the docs it says:
Behind the scenes, Django maintains a list of “authentication
backends” that it checks for authentication. When somebody calls
django.contrib.auth.authenticate() – as described in How to log a user
in – Django tries authenticating across all of its authentication
backends. If the first authentication method fails, Django tries the
second one, and so on, until all backends have been attempted.
https://docs.djangoproject.com/en/3.1/topics/auth/customizing/#specifying-authentication-backends

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.

Django DRF with React: How to obtain CSRF cookie?

I have a React frontend running at frontend.example.com and a Django backend with DRF running at backend.example.com. I am using Django Session Authentication and I want to properly implement CSRF protection.
Taking the React login page frontend.example.com/login as an example. It's the first time for a user to visit the page. There is a form with a user and password and on submit a new POST request is created to the Django backend. To the best of my knowledge, the CSRF token cookie should already be included in this request, right?
How to obtain that CSRF token from the Django backend? I am thinking of doing a GET request to the Django backend on loading the login-page to obtain that CSRF token cookie. Is that the way to do it or is there any other best practice?
Django has a section for AJAX request and how to handle CSRF: AJAX
Using this method you should send the token over and over again for each post request. The other method is using CORS. in this method, you only respond to the domains that you already whitelisted with headers that are whitelisted as well. So, instead of getting and passing CSRF token, you check if the request is coming from the right domain and then you can respond to it. And combining with a token system for user authentication, you should be good.
You can use this package for handling CORS if you use DRF: django-cors-headers
Using rate limiting can also help you avoid spams and robots to do noticeable harm.

Firebase Token Authentication using Django

I am new to django and am trying to get the user authenticated using firebase admin sdk. I am trying to do token authentication and have setup the admin sdk in my django app. Also I have received the client id token in the android app.
Now I am unable to understand how to send this id to the backend and verify it as a user and create users accordingly.I did find this answer but couldn't really understand how to go about this.
Also if a user is verified how do I add and update its data. Do I pass the token again or is there any other way to do it?
Your Android App should send its ID token along with all requests sent to the backend server. You can decide how to include that (as a header, as part of a JSON payload etc). In the backend server, you should always call auth.verify_id_token() and return an error (e.g. 401 Unauthorized) if the token fails to validate.

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!