Requests Module Python - python-requests

I have an application running with PHP and CURL.
My idea is to move the application to Python-Django-Requests.
I have been unable to work, I hope you can give me a hand please.
The application works as follows:
Collect: a number, a message and through an API sends an SMS.
PHP code.
http://pastebin.com/PqpBgstD
import requests
import cookielib
posdata = "p_num_text=00513015924048&smstemplate=&message=message_sending&txtcount=8
+char+%3A+1+Sms&hiddcount=152"
jar = cookielib.CookieJar()
user = 'xxx'
pass = 'xxx'
values = {'app': 'page', 'inc': 'login', 'op': 'auth_login',
'username': user, 'password': pass} # data login
r = requests.post(url, data=values, cookies=jar) # Login
values = {'app': 'menu', 'inc': 'send_sms',
'op': 'sendsmstopv_yes'}# values ​​to enter to send the sms
r = requests.post(url, data=values, params=posdata, cookies=jar)# enter the area sms
print r.content
How I can pass the code in CURL to Requests?
Does the above code is fine?

Your code will not work, I've attached the corrected code below, note that you don't need to use cookielib as Requests's cookie will generate a CookieJar object.
import requests
url = "http://dominio.com/subdominio/index.php"
username = 'xxx'
password = 'xxx'
payload = {
'app': 'page',
'inc': 'login',
'op': 'auth_login',
'username': username,
'password': password}
r = requests.post(url, data=payload) # Login
cSMS = "Sms"
payload = {
'p_num_text': '00513015924048',
'smstemplate': '',
'message': 'message_sending',
'txtcount': '8',
'char': cSMS, # your php code seems to be off for this one, double check it
'hiddcount': '153'}
url = "http://dominio.com/subdominio/index.php?app=menu&inc=send_sms&op=sendsmstopv_yes"
r = requests.post(url, data=payload, cookies=r.cookies) # enter the area sms
print r.text

Related

Python requests post: data and json

I used the following Python code to retrieve a web page behind a login page successfully for some years:
username = 'user'
password = 'pass'
login_url = 'https://company.com/login?url='
redirect_url = 'https://epaper.company.com/'
data = { 'email' : username, 'pass' : password }
initial_url = login_url + quote(redirect_url)
response = requests.post(initial_url, data=data)
Then something changed at company.com about 2 months ago, and the request returned status code 400. I tried changing the data parameter to json (response = requests.post(initial_url, json=data)) which gave me a 200 response telling me a wrong password was provided.
Any ideas what I could try to debug?
Thanks,
Jan
Update: I just tried using a requests session to retrieve the csrf_token from the login page (as suggested here), so now my code reads:
with requests.Session() as sess:
response = sess.get(login_url)
signin = BeautifulSoup(response._content, 'html.parser')
data['csrf_token'] = signin.find('input', {'name':'csrf_token'})['value']
response = sess.post(initial_url, data=data)
Unfortunately, the response is still 400 (and 200/wrong password with the json parameter).
First: When you send data=data, used {"Content-Type":"application/x-www-form-urlencoded"}; if you send json=data, in headers response should be used {"Content-Type":"application/json"}
Second: Perhaps redirects have been added. Try to add:
response = sess.post(url, data=data)
print("URL you expect", url)
print("Last request URL:", response.url)
Be sure to check:
print(sess.cookies.get_dict())
print(response.headers)
If you get an unexpected result when checking, change the code like this:
response = sess.post(url, data=data, allow_redirects=False)

How to get nonce for password hashing for post request?

I'm trying to gather information from a router (model BGW-210) with BS4 and Python for automation. The Wi-Fi information page requires a device access code which I have available. However, the access code is hashed with a nonce using md5 in the format of: md5('access code' + 'nonce'). The post form looks like this:
payload = {
'nonce': '',
'password': 'access code',
'hashpassword': '',
'Continue': 'Continue'
}
The router also changes each of the letter of the password into '*' for each letter in the field after hashing when I inspected the Payload in the Network tab from my browser.
Here's what I have so far
s = requests.Session()
res = s.get(bgw_210['login_url'], headers=headers)
cookies = dict(res.cookies)
headers['Content-Type']= 'application/x-www-form-urlencoded'
res = s.post(bgw_210['login_url'], headers=headers, cookies=cookies)
html = res.text
soup = BeautifulSoup(html,'html.parser')
# I can get the nonce value from here
print(soup.find('input', {"name":"nonce"}).attrs['value'])
payload = {
'nonce': '',
'password': 'access code',
#'password': '**********',
'hashpassword': '',
'Continue': 'Continue',
}
The nonce would change if I update the payload with the hash password and would no longer be valid. I've tried post requesting with fixed values from the payload that I monitored and input manually via the browser.

Urllib3 session (persist settings between requests)

I wrote a Python script which makes several https requests one after the other by following redirections (its purpose is to login to AWS Cognito via a load balancer):
import requests
session = requests.session()
response = session.get(
f'https://<initial_url>',
allow_redirects=False,
verify=False,
)
response = session.get(
response.headers["Location"],
allow_redirects=False,
verify=False,
)
response = session.post(
response.headers["Location"],
allow_redirects=False,
verify=False,
data={
"_csrf": session.cookies["XSRF-TOKEN"],
"username": <user>,
"password": <password>,
},
)
This works as expected. I would like to use the urllib3 library instead of requests and I transformed the script as follows:
import urllib3
http = urllib3.PoolManager(cert_reqs="CERT_NONE")
response = session.request(
"GET",
f'https://<initial_url>',
redirect=False,
retries=False,
)
response = session.request(
"GET",
response.headers["Location"],
redirect=False,
retries=False,
)
csrf=<get the XSRF-TOKEN cookie from response.headers["Set-Cookie"]>
fields = {
"_csrf": csrf,
"username": <user>,
"password": <password>,
}
response = session.request(
"POST",
response.headers["Location"],
redirect=False,
retries=False,
fields=fields,
)
The GET requests work and the redirects are as expected, but the POST does not (I get an error from Cognito). Based on the documentation
https://docs.python-requests.org/en/latest/user/quickstart/
and
https://urllib3.readthedocs.io/en/latest/user-guide.html
I understand that the equivalent of requests/data is urllib3/fields, as both are used to form-encode data
In the first version of the code, I created a new requests.session() object before the POST request and used it for that and I got the same error as in the urrlib3 case, which led me to believe that urllib3.PoolManager() does not provide a session like requests.session() and that each request is made separately, which makes the POST request fail. Does anyone know if there is a way to have a session in urrlib3 ? I could not find anything in the documentation

Get multiple results for different ids from single python requests

I want to get info for different user_ids from an API using python requests, I can use a loop and change the id every time, but it is slow, is there a simple way to do this?
import requests
from pprint import pprint
url = "....../api"
paras = {
'username': 'guest',
'password': '123456',
'method': 'location_info',
'barcode': ['1150764','1150765'],
}
r = requests.get(url, params=paras, verify = False)
pprint(r.json())
The result only return the info for latter barcode '1150765'. Is there a way to query 100 barcodes at the same time?

Receive Bearer Token from API with R

I'm searching for a solution to receive a Bearer token from an API using username and password.
Right now I'm reading the token through Chrome and extract my data, which is less then ideal of course.
I tried with httr and curl to optain through R and receive the Bearer token, but i think i am quite lost.
I think it should be quite simple, from the login information i gathered the mask from the login as
{"username":"name","password":"pw"}, shouldn't this just work with the POST command and the right headers?
POST(url="api_login",config=add_headers(c("username: name"
,"password: pw")))
Doesn't work at all. I can provide the example for php which looks like this:
<?php
// Include Request and Response classes
$url = 'url';
$params = array(
'username' => 'sample_username',
'password' => 'sample_password'
);
// Create a new Request object
$request = new Request($url, 'POST', $params);
// Send the request
$request->send();
// Get the Response object
$response = $request->getResponse();
if($response->getStatusCode() == 200) {
print_r($response->getBodyDecoded());
}
else {
echo $response->getStatusCode() . PHP_EOL;
echo $response->getReasonPhrase() . PHP_EOL;
echo $response->getBody() . PHP_EOL;
}
?>
As I'm not very familiar with php i would be very pleased for any help or a guide into the right direction. I searched hours
for API access through R but everything looks very specific to a special login.
I figured out this API uses a deprecated version of Swagger, if this is any useful information.
Thats what I'm doing atm, login with the website and read the token out of my browser. I want to login from inside R, sorry if I wasn't clear.
I updated my code now to:
opts=curlOptions(verbose=TRUE,
ssl.verifypeer = T)
postForm(url,
"username:" = uname, "password:"=pswd,
httpheader = c('Content-Type' = 'application/json', Accept = 'application/json'),
.opts=opts,
style='POST'
)
Which results in an error: SSL certificate problem: self signed certificate in certificate chain.
I tried a lot of different certificates with 'cainfo' inside the argument but can't make it work.

Resources