Server-Side Scripting/Cookies and Sessions/Python (Flask)
Appearance
app.py
[edit | edit source]# Demonstrates session and cookie processing. The username is stored
# as a cookie and an internal userid is saved in a session variable.
# Also demonstrates secure password authentication using bcrypt salt
# and hash.
#
# References:
# https://en.wikibooks.org/wiki/Python_Programming
# https://flask.palletsprojects.com/en/1.1.x/quickstart/
# http://zetcode.com/python/bcrypt/
import os
import flask
import bcrypt
app = flask.Flask(__name__)
app.secret_key = os.urandom(32) # 256-bit key secures session variables
FORM = """
<h1>Cookies and Sessions</h1>
<p>Cookie: {{cookie}}<br>Session: {{session}}</p>
<p>{{welcome}}</p>
<hr>
<form method="POST">
<p><label for="username">Username:</label>
<input type="text" id="username" name="username" value="{{username}}"></p>
<p><label for="password">Password:</label>
<input type="password" id="password" name="password"></p>
<input type="submit" id="log-in" name="log-in" value="Log In">
<input type="submit" id="log-out" name="log-out" value="Log Out">
<input type="submit" id="forget-me" name="forget-me" value="Forget Me">
<input type="submit" id="reload" name="Reload" value="Reload">
</form>
"""
users = [
# Password is the same as the username, just salted and hashed.
# Don't do this in a production application! Use custom passwords.
{ "userid": 1, "username": "admin",
"password": b'$2b$12$6xEcJ9bCRo3JgNWyn32fwuSoRh1pg8f81jjHpYq6NQ9Y8uDkhWOE6'},
{ "userid": 2, "username": "test",
"password": b'$2b$12$UZLEFMg9ez.n88Sjpb/ZN.VVlmyPPxHOeL/DE452Si4H3PSQSB0Pa'}
]
@app.route("/", methods=["GET"])
def root_get():
username = flask.request.cookies.get("username")
userid = flask.session.get("userid")
return build_form(username, userid)
@app.route("/", methods=["POST"])
def root_post():
if flask.request.form.get("reload", None):
return flask.redirect("/", code=200)
elif flask.request.form.get("log-out", None):
flask.session.clear()
username = flask.request.cookies.get("username")
result = build_form(username, None)
return result
elif flask.request.form.get("forget-me", None):
flask.session.clear()
result = build_form(None, None)
response = flask.make_response(result)
response.set_cookie("username", "", max_age=0)
return response
else:
username = flask.request.form["username"]
password = flask.request.form["password"]
userid = authenticate_user(username, password)
if userid:
flask.session["userid"] = userid
result = build_form(username, userid)
response = flask.make_response(result)
response.set_cookie("username", username)
return response
else:
return flask.redirect("/", code=303)
def build_form(username, userid):
cookie = str(bool(username))
session = str(bool(userid))
if username and userid:
welcome = f"Welcome back {username}! You are logged in."
elif username:
welcome = f"Welcome back {username}! Please log in."
else:
welcome = "Welcome! Please log in."
if not username:
username = ""
result = FORM
result = result.replace("{{cookie}}", cookie)
result = result.replace("{{session}}", session)
result = result.replace("{{welcome}}", welcome)
result = result.replace("{{username}}", username)
return result
def authenticate_user(username, password):
for user in users:
if user["username"] == username:
result = bcrypt.checkpw(password.encode(), user["password"])
if result:
# should track successful logins
return user["userid"]
else:
# Should track failed attempts, lock account, etc.
return None
return None
def generate_hashed_password(password):
# Use this function to generate hashed passwords to save in
# the users list or a database.
salt = bcrypt.gensalt()
hashed = bcrypt.hashpw(password, salt)
return hashed
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
Try It
[edit | edit source]Copy and paste the code above into the following free online development environment or use your own Python (Flask) compiler / interpreter / IDE.