Isomorphic fetch and Django view - django

I'm sending a POST request to Django view using isomorphic fetch.
body : "{"email":"admin#example.com","password":"11"}"
credentials : "same-origin"
headers :
Accept : "application/json"
Content-Type : "application/json"
X-CSRFToken : "mudIfipiyLUao2ZWwoEotFOUknYeVpZASNpQQ2IdadRVOe0a9n5tUqcKzwtrDuWX"
method : "POST"
When I send this request to DRF view, I can read the data using request.data. However when I send the same data to Django view, request.POST is empty.
What could be the reason?

It appears that isomorphic fetch is probably not playing a critical role in why request.POST is empty but rather that request.POST only seems to be populated by form data, not JSON data. This is supported by this quote from the Django REST Framework docs:
It (request.data) supports REST framework's flexible request parsing, rather than just supporting form data
Also, note the advice from Malcom Tredinnick:
If you're doing REST-based web service stuff ... you should ignore request.POST
This is in reference to the fact that DRF handles a lot of stuff behind the scenes for you such as serializing things and assigning to different variables and by inter-operating with the pure Django equivalents you may get weird results.

Related

Pagination Django Rest Framework POST

I'm trying to send a POST request through an endpoint with generic APIVIEW class. The response rendered through this post request needs to be paginated. The limit and offset parameters for pagination are passed in the same POST request body. How can same be implemented using the LimitOffsetPagination. I have seen seen various examples of pagination in GET requests but no luck on POST request.

Django: Send a Post Request Through Form to Another Server

I have a form on a template on my domain1 and want to send a POST request to domain2. I am using Django as the framework. I only want domain2 to accept requests from domain1 and domain2 (itself). However, I run into csrf problems.
You need a RESTful API. That's a very large topic and would be dumb/impossible to do the work for you here with the info I've been given, so here's a summary.
I suggest Django Rest Framework for making api's.
What the above means, is that when you want to do this sort of stuff (POST requests from other domains), you need a token. This is usually done with a Json Web Token. Also known as JWT's.
The process goes like this:
Get access token from other site to have permission to use the API from that site. Certain http headers, passwords, etc, are often included with this every single time data is exchanged.
Once you get a response giving you permission, you can now perform the type of request you want, with the data you want.
The data format for all this is USUALLY done with JSON. So you will have to import json, then json.dumps(obj) to turn it into valid json, and json.loads(obj) to turn your response into a python dictionary, so you can use it in your template, or wherever you want.
If you want to see an example of this, I recently made a free GoFundMe clone on my guthub. In the donate() view at the bottom, it uses the requests library, and shows how a JWT is obtained and used. You can see it there.

How to build a json REST API in django (without Django REST framework)

Preface
I have a django project. I've wired it up so it serves a bunch of views for a bunch of models. Now I want to add an endpoint which just dumps a good fraction of the database out as json.
The way I would assume you do this is add a URL to a view class / method which returns a HTTPResponseObject full of json. Unfortunately, after quite a bit of googling, all I can find are references to Django REST framework. This is the sort of thing you would think Django would provide internally not as part of an external plugin library. But searching the django docs doesn't yield an immediate answer -- I don't think there are any docs about how to build an endpoint which just serves a bunch of json.
Questions:
Do I really need "Django REST framework" to serve json in django?
Did I overlook docs in Django for serving json?
What is the canonical way to serve json in a django project?
After more googling, I found what I was looking for in the Django docs:
JsonResponse
from django.http import JsonResponse
return JsonResponse({'foo':'bar'})
I think googling using the word "REST" was kind of a red herring which made the search space always direct my queries towards "Django REST framework" which is not what I wanted, though I do want to add a RESTful API.
You can write GET API using this method, but for POST method this will not work.
For Post method we need to use some REST Library.
POST Method will check for CSRF token in the cookies and where it fails to execute the request, as your django server will treat this request as forged.
You should go with Django Rest Framework but if you want to do it yourself then:
For POST request, if the client is sending you data as JSON, then you can use the json module to read the data from the request body.
import json
def add_new_user(self, request):
data = request.body.decode('utf8')
data = json.loads(data)
If plain name/value pair is sent, then use request.POST or request.GET
Use JsonResponse to send the response
After authentication, the server usually send a token to the client. The client then sends that token when sending a request to 'protected' api end-point. A custom header (like auth_token) is used to send the token.
In the server code, you need to do something like
request.META['HTTP_AUTH_TOKEN'] to get the token (see Custom HTTP Header in Django)
There are more things to consider like CSRF token or JWT.
See this site for a complete example https://jee-appy.blogspot.com/2018/02/make-rest-api-django.html. Be warned, it use old version of django.

View design for a Django website which has a RESTful API from the get go

I am trying to build a Django powered website. I want the website to be dynamic. For example, I want the profile page for a authenticated user to contain multiple resources (like a friends list, a group list, usage history etc) and these resources should be loaded in the same area on the page by making API calls without reloading the page.
Here is my understanding of the process:
Browser on the client side requests the profile page at www.example.com/user:id
The server returns a HTTP response and sends the html, css and javascript to the browser.
To load variable resources on the webpage, for example, the friend list, the javascript makes API calls using HTTP and sending context in JSON.
The API returns a JSON response which contain the data requested.
Javascript renders the data as html and the client is able to see new content on the same page.
I thought that in order to do this, some of my server side views need to be ordinary Django views which returns an HTTP response, while some others need to be API views which return JSON.
Now here's my confusion. Let's say www.example.com/user:id is processed using an ordinary django view, while www.example.com/user/:id/friendslist is processed using an API view. Now if the user inadvertently points the browser at www.example.com/user/:id/friendslist by typing the entire URL and hits go, what happens?
If I go with the flow of logic that I mentioned above, then the view will simply return a JSON. No html, css or javascript. In this case, how will the browser know what html to display?
I am just a beginner and I am sure I got the flow of logic wrong. Can someone please point out which part I got wrong?
Now if the user inadvertently points the browser at www.example.com/user/:id/friendslist by typing the entire URL and hits go, what happens?
It depends on how you coded your server. In Django you can use is_ajax to check whether the request was AJAX or not. You could return an HTTP error code when the request is not an AJAX one, if you wanted. So a user who inadvertently points the browser to your URL but does not take any further action will get an error.
Note here that a knowledgeable user could circumvent is_ajax by setting the request header field HTTP_X_REQUESTED_WITH to XMLHttpRequest manually.
If I go with the flow of logic that I mentioned above, then the view will simply return a JSON. No html, css or javascript. In this case, how will the browser know what html to display?
Setting your returned data type to application/json already tells the browser what it is dealing with. The least a browser would do this with this is display it as text.
Here's an example of an API call that returns JSON: https://api.zotero.org/users/475425/collections/9KH9TNSJ/items?format=json My browser just shows the JSON.

Correct method to create a login using angularjs resource and RESTApi

I used Django Tastypie to build my api and i'm thinking in the correct way to create a login form so the user can login in the application, right now what I do is send a GET request with username/password he submited in the form as filtering options, but i'm pretty sure thats not secure at all. How can i do the same using POST request?
When i open the console with firebug:
GET URL/app/api/v1/user/?email=USER&password=PASS
Api-Auth and Content-Type are on the header.
#leosilvano
Don't handle user authentication and authorization using angular js not that its impossible but just that its not too secure and implementing also take some effort when Django's provides something which far easy than this.
I happen to be using django + angularjs + tastypie (REST API ). If you like take a look at my way of implementation.
Include your index.html of the angularJs in your templates ( Django Templates ) and place your directives, controllers, js, css and etc in the static folder ( Django Static ). Make your API calls after the auth processes. This will work seamlessly and you will run into less issues as well.
Reasons:
user_auth models becomes so handy while registering and logging in using templates and you don't need to sweat trying to write your own authentication which i'm sure you have to do when you go with Angular Js login auth implementation.
Use of decorators like for a view lets say "profile" if you need to check if the user is logged in all you need to do it something like the following
#login_required(login_url='/login/')
def profile(request):
return render_to_response('profile.html')
Passing password through "GET" is bad .. and passing auth values through "POST" and getting it via JSON .. is also not a good idea. Because you will be susceptible to middle-man attacks ..
Remember you have to take measures for CORS requests when using Angularjs for login since anyone can view the json response and they will be able to reproduce the same structure. Implementing Perm-Mixins and Groups is way more easier when using Django templates.
Handling exceptions like 404 or if you want to handle only post requests and thereby take user to a custom page ( actions like redirect ) becomes difficult. I am aware of SPA's but still if there happens to be redirection .. in my case i needed to redirect to another site. Following shows how simple it can be achieved including http statuses.
if request.method != 'POST':
return HttpResponseNotFound(render_to_response('404.html', { 'message' : 'Only POST Requests are allowed for authentication process.', 'baseurl' :request.build_absolute_uri('/').rstrip('/')}))
Solution:
Use Angular Js and REST (Tastypie) interaction to happen after you login. Use Django template for login authorization. Make use of the django modules .. it saves a lot of time.
If you still want to login using REST API .. by send post to django .. please take a look at the following post
How can I login to django using tastypie
You can POST data using the $http module
Just do:
$http.post(url, data)
Always send authentication data through https or your password will be sent in clear text.