2

My Django website is hosted using Apache server. I want to send data using requests.post to my website using a python script on my pc but It is giving 403 forbidden.

import json


url = "http://54.161.205.225/Project/devicecapture"
headers = {'User-Agent':
           'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36',
           'content-type': 'application/json'}


data = {
    "nb_imsi":"test API",
    "tmsi1":"test", 
    "tmsi2":"test",
    "imsi":"test API", 
    "country":"USA", 
    "brand":"Vodafone", 
    "operator":"test",
    "mcc":"aa", 
    "mnc":"jhj",
    "lac":"hfhf", 
    "cellIid":"test cell"
}
response = requests.post(url, data =json.dumps(data),headers=headers) 

print(response.status_code)

I have also given permission to the directory containing the views.py where this request will go. I have gone through many other answers but they didn't help. I have tried the code without json.dumps also but it isn't working with that also. How to resolve this?

Kushal Vijay
  • 86
  • 1
  • 11
  • Does your endpoint requires authentication? You are not passing any and you are getting a Forbidden error – gdef_ Apr 13 '20 at 03:20
  • Is your production site running on HTTPS? Because you are posting to a URL on HTTP. Also, does your Django site allow access on the host address of that IP address you mentioned? – Rob Kwasowski Apr 13 '20 at 03:25
  • No, my production site is running on HTTP @RobKwasowski How to allow access to any other IP ? – Kushal Vijay Apr 13 '20 at 03:27
  • @gdef_ Yes I need to login before doing anything on that website. Is that causing the issue, How can resolve that ? – Kushal Vijay Apr 13 '20 at 03:28
  • Yes, a required login would explain it. – Rob Kwasowski Apr 13 '20 at 03:32
  • But, If you paste this URL = "http://54.161.205.225/Project/devicecapture" in your browser, it is giving the desired response. So I think login is not causing any problem @RobKwasowski – Kushal Vijay Apr 13 '20 at 03:35
  • I also tried the URL in a browser and received the response "Hello". In this instance you are only doing a GET request, and not a POST request, like you are attempting in your question. For a POST request you need to be authenticated or logged in. It's the same as trying to delete an email from your Gmail account without being logged in, the server will not allow it. – Rob Kwasowski Apr 13 '20 at 03:40
  • How should I authenticate my request so that error will be resolved. @gdef_ – Kushal Vijay Apr 13 '20 at 04:22
  • Did you try my answer? – Rob Kwasowski Apr 17 '20 at 01:27

2 Answers2

3

After investigating it looks like the URL that you need to post to in order to login is: http://54.161.205.225/Project/accounts/login/?next=/Project/

You can work out what you need to send in a post request by looking in the Chrome DevTools, Network tab. This tells us that you need to send the fields username, password and csrfmiddlewaretoken, which you need to pull from the page.

You can get it by extracting it from the response of the first get request. It is stored on the page like this:

<input type="hidden" name="csrfmiddlewaretoken" value="OspZfYQscPMHXZ3inZ5Yy5HUPt52LTiARwVuAxpD6r4xbgyVu4wYbfpgYMxDgHta">

So you'll need to do some kind of Regex to get it. You'll work it out.

enter image description here

So first you have to create a session. Then load the login page with a get request. Then send a post request with your login credentials to that same URL. And then your session will gain the required cookies that will then allow you to post to your desired URL. This is an example below.

import requests

# Create session
session = requests.session()

# Add user-agent string
session.headers.update({'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) ' +
'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36'})

# Get login page
response = session.get('http://54.161.205.225/Project/accounts/login/?next=/Project/')

# Get csrf
# Do something to response.text

# Post to login
response = session.post('http://54.161.205.225/Project/accounts/login/?next=/Project/', data={
    'username': 'example123',
    'password': 'examplexamplexample',
    'csrfmiddlewaretoken': 'something123123',
})

# Post desired data
response = session.post('http://url.url/other_page', data={
    'data': 'something',
})

print(response.status_code)

Hopefully this should get you there. Good luck.

For more information check out this question on requests: Python Requests and persistent sessions

Rob Kwasowski
  • 2,690
  • 3
  • 13
  • 32
1

I faced that situation many times The problems were :

  1. 54.161.205.225 is not added to allowed hosts in settings.py
  2. the apache wsgi is not correctly configured

things might help with debug :

Check apache error-logs to investigate what went wrong
try running server locally and post to it to make sure prob is not related to apache

octopus
  • 151
  • 1
  • 8