Django rejects Requests' CSRF Token - python

I'm writing an Ajax post with python's Request's library to a django backend
Code:
import requests
import json
import sys
URL = 'http://localhost:8000/'
client = requests.session()
client.get(URL)
csrftoken = client.cookies['csrftoken']
data = { 'file': "print \"It works!\"", 'fileName' : "JSONtest", 'fileExt':".py",'eDays':'99','eHours':'1', 'eMinutes':'1' }
headers = {'Content-type': 'application/json', "X-CSRFToken":csrftoken}
r = requests.post(URL+"au", data=json.dumps(data), headers=headers)
Django gives me a 403 error stating that the CSRF token isn't set even though the request.META from csrf_failure() shows it is set. Is there something I'm missing or a stupid mistake I'm not catching?

I asked my friend and he figured out the problem, basically you have to send the cookies that django gives you every time you do a request.
corrected:
cookies = dict(client.cookies)
r = requests.post(URL+"au", data=json.dumps(data), headers=headers,cookies=cookies)

You need to pass the referer to the headers, from the django docs:
In addition, for HTTPS requests, strict referer checking is done by
CsrfViewMiddleware. This is necessary to address a Man-In-The-Middle
attack that is possible under HTTPS when using a session independent
nonce, due to the fact that HTTP ‘Set-Cookie’ headers are
(unfortunately) accepted by clients that are talking to a site under
HTTPS. (Referer checking is not done for HTTP requests because the
presence of the Referer header is not reliable enough under HTTP.)
so change this:
headers = {'Content-type': 'application/json', "X-CSRFToken":csrftoken, "Referer": URL}

Related

How to Resolve Status 401 in HTTP Post Request Python?

I am trying to make an http post request in Python. The http that I am posting to requires an authorization. For security, I have replaced the real url, data and authorization. When I run the code below with the correct url, data body and authorization I get status 401. That would imply that the authorization is not correct. Is there another way I should be adding authorization, headers and body to my http post request so that the post is successful? The authorization password is correct and works in Postman, so it's contents is not the issue--I'm wondering if the format is. Thanks in advance!
import requests
from requests.auth import HTTPBasicAuth
def post():
url = 'http://somelongurl'
headers = {'Content-Type': 'application/json'}
auth = HTTPBasicAuth('Authorization', 'PASSWORD')
data = {"ProductID" : "ABCDEFG",
"ClientID": "10000",
"SerialNumber": "1234567890"}
req = requests.post(url, headers=headers, data=data, auth=auth)
return req
This was resolved by including the authorization in the headers and changing the data as type json as follows: https://postimg.cc/3y7B6fvL

Python request gives 415 error while post data

I am getting 415 error while posting data to server. This is my code how can i solve this problem. Thanks in advance!
import requests
import json
from requests.auth import HTTPBasicAuth
#headers = {'content-type':'application/javascript'}
#headers={'content-type':'application/json', 'Accept':'application/json'}
url = 'http://IPadress/kaaAdmin/rest/api/sendNotification'
data = {"name": "Value"}
r = requests.post(url, auth=HTTPBasicAuth('shany.ka', 'shanky1213'),json=data)
print(r.status_code)
According to MDN Web Docs,
The HTTP 415 Unsupported Media Type client error response code
indicates that the server refuses to accept the request because the
payload format is in an unsupported format.
The format problem might be due to the request's indicated
Content-Type or Content-Encoding, or as a result of inspecting the
data directly.
In your case, I think you've missed the headers.
Uncommenting
headers={
'Content-type':'application/json',
'Accept':'application/json'
}
and including headers in your POST request:
r = requests.post(
url,
auth=HTTPBasicAuth('shany.ka', 'shanky1213'),
json=data,
headers=headers
)
should do the trick
import requests
import json
from requests.auth import HTTPBasicAuth
headers = {
'Content-type':'application/json',
'Accept':'application/json'
}
url = 'http://IPadress/kaaAdmin/rest/api/sendNotification'
data = {"name": "Value"}
r = requests.post(
url,
auth=HTTPBasicAuth('shany.ka', 'shanky1213'),
json=data,
headers=headers
)
print(r.status_code)
As a workaround, try hitting your api using Postman. When you can successfully hit the api in postman, generate python code in postman (button is present in the top right corner). You can copy the code in your python project.
Another possible cause is using requests.post when you should be using requests.get or vice versa. I doubt that this is a common problem, but in my case a server that was happy to accept an HTTP GET for a search rejects it with a 415 when HTTP POST is used instead. (Yet another site required that a search be requested using HTTP POST. It was reusing that code that caused my problem.)

Is this a Post request issue or an SSL verification issue

I'm trying to use a certain company's (not yet public) API. In their documentation they lay out the format of the Token request. Here's a copy of the documentation for a Token request:
POST
https://***.****.com/auth/realms/****/protocol/openid-connec
t/token
Headers:
Content-Type: application/x-www-form-urlencoded
Authorization: Basic {base64-encoded-key-and-secret}
Body: grant_type:client_credentials
The authorization key was given to me by them and is of the form 'Basic a3RhdmlfdG...'
I'm trying to write a Post request in python and I'm having issues and I'm not sure if it's my fault or their developers fault. Here's my code:
url = 'https://***.****.com/auth/realms/****/protocol/openid-connect/token'
headers = {'Content-Type':'application/x-www-urlencoded', 'Authorization':'Basic a3RhdmlfdG...'}
body = {'grant_type':'client_credentials'}
response = requests.post(url = url, data = json.dumps(body), headers = headers)
print response
At the line where response = ...I'm getting an SSL: CERTIFICATE_VERIFY_FAILED error. I've also tried changing the values in the headers to random values and I get the same error. I can think of three possibilities, either
I'm making the Post request incorrectly
There is a problem with the API
I'm missing a certificate which I have to send with the Post request
Is it one of these issues or is it something else?
They are probably using a self signed cert. You can bypass the verify check by adding 'verify=False'. I would remove that before going to production. It is important that SSL certs are valid.
response = requests.post(url = url, data = json.dumps(body), headers = headers, veryify=False)

Post request using Python urllib

I'm making a request to an api using python3 urllib. This is my code,
headers = {}
headers['Content-Type']='application/x-www-form-urlencoded; charset=UTF-8'
#headers['X-Csrf-Token']= {'mode: cors'}
req = urllib.request.Request(url=URL, headers=headers, method='POST')
res = urllib.request.urlopen(req)
print(res.read())
I get the following response,
urllib.error.HTTPError: HTTP Error 415: Unsupported Media Type
The API endpoint is working fine and I've tested it with Postman. This is the equivalent javascript code which gets the job done,
return fetch(url, { credentials : 'include', method: 'post'})
So I'm assuming I've to find a way to add credentials to the header. Can I do a credentials include parallel in Python or do I have to fetch the specific cookie and set it in the request. Any help appreciated.
The error 415 indicates an issue with 'Content-type'.
'application/x-www-form-urlencoded' does not have any parameters.
https://www.w3.org/TR/html5/iana.html#application/x-www-form-urlencoded
Regarding fetch()'s "credentials", you would need the ability to maintain a session (sending cookies as required).
It is much easier with the requests library's Session
http://docs.python-requests.org/en/master/user/advanced/#session-objects

Python create cookies and then load a page with the cookies

I would like to access a web page from a python program.
I have to set up cookies to load the page.
I used the httplib2 library, but I didn't find how add my own cookie
resp_headers, content = h.request("http://www.theURL.com", "GET")
How can I create cookies with the right name and value, add it to the function and then load the page?
Thanks
From http://code.google.com/p/httplib2/wiki/Examples hope will help )
Cookies
When automating something, you often need to "login" to maintain some sort of session/state with the server. Sometimes this is achieved with form-based authentication and cookies. You post a form to the server, and it responds with a cookie in the incoming HTTP header. You need to pass this cookie back to the server in subsequent requests to maintain state or to keep a session alive.
Here is an example of how to deal with cookies when doing your HTTP Post.
First, lets import the modules we will use:
import urllib
import httplib2
Now, lets define the data we will need. In this case, we are doing a form post with 2 fields representing a username and a password.
url = 'http://www.example.com/login'
body = {'USERNAME': 'foo', 'PASSWORD': 'bar'}
headers = {'Content-type': 'application/x-www-form-urlencoded'}
Now we can send the HTTP request:
http = httplib2.Http()
response, content = http.request(url, 'POST', headers=headers, body=urllib.urlencode(body))
At this point, our "response" variable contains a dictionary of HTTP header fields that were returned by the server. If a cookie was returned, you would see a "set-cookie" field containing the cookie value. We want to take this value and put it into the outgoing HTTP header for our subsequent requests:
headers['Cookie'] = response['set-cookie']
Now we can send a request using this header and it will contain the cookie, so the server can recognize us.
So... here is the whole thing in a script. We login to a site and then make another request using the cookie we received:
#!/usr/bin/env python
import urllib
import httplib2
http = httplib2.Http()
url = 'http://www.example.com/login'
body = {'USERNAME': 'foo', 'PASSWORD': 'bar'}
headers = {'Content-type': 'application/x-www-form-urlencoded'}
response, content = http.request(url, 'POST', headers=headers, body=urllib.urlencode(body))
headers = {'Cookie': response['set-cookie']}
url = 'http://www.example.com/home'
response, content = http.request(url, 'GET', headers=headers)
http = httplib2.Http()
# get cookie_value here
headers = {'Cookie':cookie_value}
response, content = http.request("http://www.theURL.com", 'GET', headers=headers)
You may want to add another header parameters to specify another HTTP request parameters.
You can also use just urllib2 library
import urllib2
opener = urllib2.build_opener()
opener.addheaders.append(('Cookie', 'cookie1=value1;cookie2=value2'))
f = opener.open("http://www.example.com/")
the_page_html = f.read()

Categories