How to logout in Python Bottle? - python-3.x

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?

Related

How do I check for a session variable in flask repeatedly across the application?

I'm looking for an efficient way to check a session variable for each view. I can do it like below per the docs, but is there a global function or decorator that could extract the username without repeating the same lines?
#app.route('/')
def index():
if 'username' in session: # this is repeated in every view
username = session['username'] # this is repeated in every view
return 'You are not logged in'
Your guess is correct. A decorator is a way to review the session and react to the result. In the example below, the user is redirected to the appropriate route based on the decorator if the user is not logged in. If a username is stored in the session, the decorated route is called.
If the login is optional for the respective route, it is public and no decorator is required. But it might be necessary to ask if the user is logged in.
from flask import (
redirect,
session,
url_for
)
from functools import wraps
# ...
def is_authenticated():
username = session.get('username')
return username and len(username.strip()) > 0
def login_required(f):
#wraps(f)
def wrapper(*args, **kwargs):
if not is_authenticated():
return redirect(url_for('login'))
return f(*args, **kwargs)
return wrapper
# Add the state query function to the jinja context.
app.jinja_env.globals.update(is_authenticated=is_authenticated)
#app.route('/login', methods=['GET', 'POST'])
def login():
# your login code here!
#app.route('/secret')
#login_required
def secret():
return 'You are logged in.'
#app.route('/public')
def public():
if is_authenticated():
return 'User is authenticated'
return 'User is not authenticated'
This code is used to check within the template whether the user is logged in.
{% if is_authenticated() %}
User is authenticated.
{% else %}
User is not authenticated.
{% endif %}
If you really want to ask for the session variable before each route, the before_request decorator might be a solution. In this case you cannot avoid storing variables in the g object to use them in your routes. However, this goes beyond your example or unnecessarily complicates the code as it only becomes necessary to use additional data.
I think the code I gave should be enough for simple purposes.
For more complex environments I recommend you take a look at Flask-Login or Flask-Security.

Logging in to Steam using Scrapy, login and 2FA

I would like to log into Steam to try my hand at some data collection but I don't really know how to go about logging in and getting past 2FA. My current code tries to log in and is supposed to save the result of that into an html file so I could see what was achieved. It currently returns a blank html file.
import scrapy
def authentication_failed(response):
pass
class LoginSpider(scrapy.Spider):
name = 'loginSpider'
start_urls = ['https://steamcommunity.com/login/home/?goto=']
def parse(self, response):
return scrapy.FormRequest.from_response(
response,
formdata={'username': 'user', 'password': 'pwd'},
callback=self.after_login
)
def after_login(self, response):
if authentication_failed(response):
self.logger.error("Login failed")
return
html = open("test.html", "w")
html.write(response.body.decode("utf-8"))
html.close()
To spare me asking another question, would getting through the Steam Guard 2FA system be as simple as asking the user to type the code in and then sending another FormRequest?

Python authorization

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)

cannot create flask login test function

I have a login function with user and pass parameters that returns a token. I'am using flask.
Now i need a test case to test my function, i am lost here.
Neve done testing and i can't come up with the solution.
I need a test case that verifies a token was created when the login is made.
Any help?
def login():
user = request.form['user']
passwd = request.form['passwd']
test = ldap.bind_user(user, passwd)
if test is None or passwd == '':
response = jsonify(message='Invalid Credentials')
return response ,401
access_token = create_access_token(identity=user)
return jsonify(access_token=access_token), 200```
After 2 days i finally manage to come up with the solution.
I checked if access_token was in the response.data
def test_token_sent(self):
tester = app.test_client(self)
response = tester.post(
'/login',
data =dict(user="hermes", passwd ="hermes"),
follow_redirects=True)
self.assertIn(b'access_token', response.data)```

#flask_login.login_required not working properly

I am using flask_login for implementing auth in my flask application
Here are the unauthorized_handler and login_required enabled method
#login_manager.unauthorized_handler
def unauthorized_handler():
return redirect(url_for('login'))
# use decorators to link the function to a url
#app.route('/profile', methods=['GET'])
#flask_login.login_required
def profile():
return render_template('profile.html')
I am using firebase as my backend service
#app.route('/login', methods=['GET', 'POST'])
def login():
auth = firebase.auth()
if request.method == 'POST':
try:
user = auth.sign_in_with_email_and_password(request.form['email'], request.form['password'])
if user != None:
return redirect(url_for('profile'))
except requests.exceptions.HTTPError as e:
response = e.args[0].response
error = response.json()['error']['code']
return redirect(url_for('home'))
return render_template('login.html')
The problem is that after I login(which is successfull) the app is automatically redirected to the /login url instead of /profle.
I tried turning my debug mode off and on still not working.
It can be a case of a double redirect happening, where you first get redirected to profile, and then the login_required decorator kicks in redirecting you back to login, because from the point of view of flask_login you are not logged in yet.
You might have retrieved user credentials from firebse, but with flask_login you have to also call login_user function. (Also see Login Example of flask login's page)

Resources