Python authorization - python-3.x

I need to write a script that is included in the personal account of my Internet provider and transmits information about the current balance.
At the moment I am stuck at the time of authorization. I found and edited such a script for myself:
import requests
url = 'https://bill.tomtel.ru/login.html'
USERNAME, PASSWORD, = 'mylogin', 'mypass'
resp = requests.get(url, auth=(USERNAME, PASSWORD))
r = requests.post(url)
print(r.content)
But this does not help to pass authorization...
I can enter this link through a browser and go to a page of this type:
https://bill.tomtel.ru/fastcom/!w3_p_main.showform?FORMNAME=QFRAME&CONFIG=CONTRACT&SID=BLABLABLA&NLS=WR
I can go through browser authorization through both links, but why can't I do this through a script?
Please help with this.

Your browser probably has a session token/cookie stored and that is why you can access it through the browser. There are a couple issues here:
It looks like you need to login to the site first -- through a POST method, not a GET. The GET is what loads the page. But once you submit the form it's going to do a POST request.
Actually, using requests to login to a site is not as easy as it looks. Usually you have to find the url it's posting to (examine the developer toolbar to see the url), and you often have to pass information in addition to your username/password, such as a csrf token, a cookie, or something else.
I would suggest using a browser-automator for this, perhaps something like selenium Webdriver. It makes logging into a site much simpler than using HTTP in a raw request, as it emulates a browser. I would suggest this -- it's much simpler and faster!
Another thing to note: auth=(USERNAME, PASSWORD) is not quite the username/password in the form (it's something else) but I don't think understanding that is too relevant to what you're trying to do.
Here is the url and required form data to log in:

I think you should try this:
import requests
url = 'https://bill.tomtel.ru/signin.php'
USERNAME = input('Enter your username: ')
PASSWORD = input('Enter your password: ')
d = {
'USERNAME' : USERNAME,
'PASSWORD' : PASSWORD,
'FORMNAME' : 'QFRAME'}
session = requests.Session()
resp = session.post(url, data=d).text
if not '<TITLE>' in resp:
print('Incorrect username or password!')
quit()
print('Logging in ... ')
for line in resp.split('\n'):
if 'location' in line:
red = 'https://bill.tomtel.ru/fastcom/!w3_p_main.showform%s' % line.replace(' if (P>0) self.location.replace("', '').replace('");', '')
if not red:
print('An error has occured')
quit()
print('Redirecting to %s' % red)
page = session.get(red).text
print('')
print(' MAIN PAGE')
print(page)

Related

python using requests and a webpage with a login issue

I'm trying to login to a website via python to print the info. So I don't have to keep logging into multiple accounts.
In the tutorial I followed, he just had a login and password, but this one has
Website Form Data
Does the _wp attributes change each login?
The code I use:
mffloginurl = ('https://myforexfunds.com/login-signup/')
mffsecureurl = ('https://myforexfunds.com/account-2')
payload = {
'log': '*****#gmail.com',
'pdw': '*****'
'''brandnestor_action':'login',
'_wpnonce': '9d1753c0b6',
'_wp_http_referer': '/login-signup/',
'_wpnonce': '9d1753c0b6',
'_wp_http_referer': '/login-signup/'''
}
r = requests.post(mffloginurl, data=payload)
print(r.text)
using the correct details of course, but it doesn't login.
I tried without the extra wordpress elements and also with them but it still just goes to the signin page.
python output
different site addresses, different login details
Yeah the nonce will change with every new visit to the page.
I would use request.session() so that it automatically stores session cookies and all that good stuff.
Do a session.GET('some_login_page.com')
Parse with the response content with BeautifulSoup to retrieve the nonce.
Then add that into the payload of your POST request when you login.
A very quick and dirty example:
import requests
from bs4 import BeautifulSoup as bs
email = 'test#email.com'
password = 'password1234'
url = 'https://myforexfunds.com/account-2/'
# Start a session
with requests.session() as session:
# Send a GET request to the login page
r = session.get(url)
# Check if the request was successful
if r.status_code != 200:
print("Get Request Failed")
# Parse the HTML content of the page
soup = bs(r.content, 'lxml')
# Extract the value of the nonce from the HTML
nonce = soup.find(id='woocommerce-login-nonce')['value']
# Set up the login form data
params ={
"username": email,
"password": password,
"woocommerce-login-nonce": nonce,
"_wp_http_referer": "/account-2/",
"login": "Log+in"
}
# Send a POST request with the login form data
r = session.post(url, params=params)
# Check if the request was successful
if r.status_code != 200:
print("Login Failed")

Empty token with Python Requests, but multiple tokens seen in chrome dev tools

I'm trying to use requests to login to a site, navigate to a page, and scrape some data. This question is about the first step (to get in).
I cannot fetch the token from the site:
import requests
URL = 'https://coderbyte.com/sl'
with requests.Session() as s:
response = s.get(URL)
print([response.cookies])
Result is empty:
[<RequestsCookieJar[]>]
This make sense according to the response I'm seeing in Chrome's dev tools. After I login with my username and password, I see four tokens, three of them deleted, but one valid:
How can I fetch the valid token?
you can use the post method to the url you want in order to fetch the token (to pass the login first). For example :
url = "url-goes-here"
url_login = "login-url-goes-here"
with requests.Session() as s:
# get the link first
s.get(url)
payload = json.dumps({
"email" : "your-email",
"password" : "your-password"
})
headers = {
'Content-Type': 'application/json'
}
response = s.post(url=url_login, data=payload, headers=headers)
print(response.text)
Based on your question, i assume that if you only use username or password to login, then you can use HTTPBasicAuth() which is provided by requests package.

Flask - b' text appears before request.data results

So I for a while I was running my application on Python's Localhost for debugging reasons, but now I desperately want to make my Flask application run on my Apache Localhost. I have configured Ubuntu on Vagrant to run the application on Apache and the only thing that does not work right now is the Facebook Sign-In. While my Google Sign-in method works fine on both Python's Localhost and on Apache, my Facebook Sign-in method only works on Python's Localhost and NOT on Apache's Localhost for some reason.
Specifically, in my fbconnect() method that preforms the fb sign-in functionality, when the code reaches my 4th print( print("4. FB http request results: %s" % result) ) of the given code block (scroll down for the block of code), the message given off by the 4th print is this error:
4. FB http request results: b'{"error":{"message":"Invalid OAuth access token.","type":"OAuthException","code":190,"fbtrace_id":"AjWGMxq54MULV0sCpjpW2DT"}}'
I don't know what the b' is doing there (it appears right at the start of the error message) and how to remove it, but it also appears in the 1st print( _print("1. Access token: %s " % access_token)_ ) :
1. Access token: b'EAAE7dgXeMUup...'
and it does NOT appear in the 2nd or the 3rd print:
2. App ID: 3425...
3. App secret: 75a2...
I think that the problem is caused by those b' since they do not appear in my prints when I run the app on my Python Localhost and they also do not appear in the 2nd or 3rd prints on Apache, but I'm not sure as they might be appearing because the print output is somehow changed when I write out the messages in a 'print.log' file, since Apache doesn't actually print out messages to the terminal like Python's Localhost does.
Here's my fbconnect() method:
def fbconnect():
''' Validate state token, by confirming that the token that the client sends
to the server matches the token that the server sent to the client. This
round-trip verification helps ensure that the user is making the request
not a malicious script. Using the request.args.get() method, we examine
the state token passed in by the ajax request and compare with the state
of the login_session. If these 2 do NOT match, we create a response of an
invalid state token and return this message to the client. '''
if request.args.get('state') != login_session['state']:
response = make_response(json.dumps('Invalid state parameter.'), 401)
response.headers['Content-Type'] = 'application/json'
return response
access_token = request.data
print("1. Access token: %s " % access_token)
# Get Facebook app ID.
app_id = json.loads(open('/vagrant/Inhinito/fb_client_secrets.json', 'r').read())['web']['app_id']
print("2. App ID: %s " % app_id)
# Get Facebook app secret.
app_secret = json.loads(open('/vagrant/Inhinito/fb_client_secrets.json', 'r').read())['web']['app_secret']
print("3. App secret: %s " % app_secret)
# Make http request to the Facebook API.
url = "https://graph.facebook.com/oauth/access_token?client_id=%s" % (app_id)
url += "&client_secret=%s&grant_type=fb_exchange_token" % (app_secret)
url += "&fb_exchange_token=%s" % (access_token)
http = httplib2.Http()
result = http.request(url, 'GET')[1]
print("4. FB http request results: %s" % result)
....
Here's the correct output that I get from Python's Localhost:
1. Access token: EAgE7...
4. FB http request results: {"access_token":"EAgE7...","token_type":"bearer","expires_in":5183999}
As Doobeh mentioned in the comments the solution is to decode the data sent by the client-side to UTF-8. This is a Python2 vs Python3 issue explained in detail here.
The b' ' apparently is used to indicate the string is binary, as opposed to Unicode.
The solution is to use
access_token = request.data.decode('UTF-8')
Instead of
access_token = request.data and
http.request(url, 'GET')[1].decode('UTF-8') instead of http.request(url, 'GET')[1].

Request module python

I'm having trouble using Python's request module.I'm trying to login to a webpage but it does not allow my connection.I don't really know if it might be a validation problem. Here is the code I'm using and the link of the page. It never shows me the page (The one I'm trying to access after I log in).
import requests
with requests.Session() as c:
username = "*******"
password = "******"
payload = {"userPri": username, "password": password}
url="https://declaraciones.sri.gob.ec/tuportalinternet/verificaEmail.jspa"
c.post("",data=payload)
page=c.get("another webpage")
print (page.content)`

How to logout in Python Bottle?

I have the following test snippet:
def check(username, password):
if username == "b" and password == "password":
return True
return False
#route('/logout')
#route('/logout', method="POST")
def logout():
# template with a logout button
# this does redirect successfully, but this shouldn't happen
redirect('/after-login')
#route('/after-login')
#auth_basic(check)
def after_login():
return "hello"
#route('/login')
#route('/login', method="POST")
def login():
return template("views/login/login_page")
username = post_get('username')
password = post_get('password')
I'm attempting to log out of the system, but I haven't been able to find any resources on how to do this. Basically, I tried dir(response) and dir(request) and haven't found any functions that appears to set the session off (mostly attempting to reset cookies), unless I close the browser.
Issued the same problem. Well, The decision I found in docs and used is response.delete_cookie('<cookiename>')
So every time I enter the page with setting any cookies, first I delete all possibble to change cookies.
You want to log out of HTTP Basic Auth, which is not really what it was designed for. But there does seem to be a way: return an HTTP 401.
from bottle import abort
#route('/logout', method=["GET", "POST"])
def logout():
abort(401, "You're no longer logged in")
Does this work?

Resources