{% raw %}
Flask 和登录验证

Flask 图标
在本教程中,您将学习如何使用 Flask 和 Python 构建登录 Web 应用程序。
建立一个 Flask 登录页面
创建此 Python 文件并将其另存为app.py:
from flask import Flaskfrom flask import Flask, flash, redirect, render_template, request, session, abortimport osapp = Flask(__name__)@app.route('/')def home():if not session.get('logged_in'):return render_template('login.html')else:return "Hello Boss!"@app.route('/login', methods=['POST'])def do_admin_login():if request.form['password'] == 'password' and request.form['username'] == 'admin':session['logged_in'] = Trueelse:flash('wrong password!')return home()if __name__ == "__main__":app.secret_key = os.urandom(12)app.run(debug=True,host='0.0.0.0', port=4000)
在此处创建了两条路由(您可以在浏览器 URL 栏中看到的路径):
@app.route('/')@app.route('/login', methods=['POST'])
第一个显示基于登录条件的登录屏幕或主屏幕。第二个路由在登录时验证登录变量。
我们创建目录/templates/。 使用以下代码创建文件/templates/login.html:
{% block body %};{% if session['logged_in'] %};You're logged in already!{% else %};<form action="/login" method="POST"><input type="username" name="username" placeholder="Username"><input type="password" name="password" placeholder="Password"><input type="submit" value="Log in"></form>{% endif %};{% endblock %};{% endraw %};
使用以下命令运行 Web 应用程序:
$ python hello.py
在您的网络浏览器中打开 http://localhost:5000/ ,然后会出现登录屏幕。 登录凭据显示在do_admin_login()函数中。

Pythonspot.com 登录界面
使它看起来很棒
功能正常时,登录屏幕看起来像 90 年代初期的用户界面(UI)。 我们从 codepen.io 中选择了一个随机登录模板。 我们使用文件style.css创建目录/static/。
* {box-sizing: border-box;}*:focus {outline: none;}body {font-family: Arial;background-color: #3498DB;padding: 50px;}.login {margin: 20px auto;width: 300px;}.login-screen {background-color: #FFF;padding: 20px;border-radius: 5px}.app-title {text-align: center;color: #777;}.login-form {text-align: center;}.control-group {margin-bottom: 10px;}input {text-align: center;background-color: #ECF0F1;border: 2px solid transparent;border-radius: 3px;font-size: 16px;font-weight: 200;padding: 10px 0;width: 250px;transition: border .5s;}input:focus {border: 2px solid #3498DB;box-shadow: none;}.btn {border: 2px solid transparent;background: #3498DB;color: #ffffff;font-size: 16px;line-height: 25px;padding: 10px 0;text-decoration: none;text-shadow: none;border-radius: 3px;box-shadow: none;transition: 0.25s;display: block;width: 250px;margin: 0 auto;}.btn:hover {background-color: #2980B9;}.login-link {font-size: 12px;color: #444;display: block;margin-top: 12px;}
将login.html模板修改为:
<link rel="stylesheet" href="/static/style.css" type="text/css">{% block body %};<form action="/login" method="POST"><div class="login"><div class="login-screen"><div class="app-title"><h1>Login</h1></div><div class="login-form"><div class="control-group"><input type="text" class="login-field" value="" placeholder="username" name="username"><label class="login-field-icon fui-user" for="login-name"></label></div><div class="control-group"><input type="password" class="login-field" value="" placeholder="password" name="password"><label class="login-field-icon fui-lock" for="login-pass"></label></div><input type="submit" value="Log in" class="btn btn-primary btn-large btn-block"></div></div></div></form>{% endblock %};
重新启动应用程序后,将出现以下屏幕:

Python Flask 登录界面
很棒,不是吗? :-)
那么注销呢?
如您所见,没有注销按钮或功能。 创建起来非常容易。 下面提出的解决方案只是众多解决方案之一。 我们创建一个新的路由/logout,它直接指向函数logout()。 此函数清除会话变量并返回登录屏幕。
@app.route("/logout")def logout():session['logged_in'] = Falsereturn home()
完整代码:
from flask import Flaskfrom flask import Flask, flash, redirect, render_template, request, session, abortimport osapp = Flask(__name__)@app.route('/')def home():if not session.get('logged_in'):return render_template('login.html')else:return "Hello Boss! <a href="/logout">Logout</a>"@app.route('/login', methods=['POST'])def do_admin_login():if request.form['password'] == 'password' and request.form['username'] == 'admin':session['logged_in'] = Trueelse:flash('wrong password!')return home()@app.route("/logout")def logout():session['logged_in'] = Falsereturn home()if __name__ == "__main__":app.secret_key = os.urandom(12)app.run(debug=True,host='0.0.0.0', port=4000)
连接数据库
如果要使用多用户登录系统,则应在应用程序中添加一个数据库层。Flask 没有现成的数据库支持。 如果要数据库支持,则必须使用第三方库。 在本教程中,我们将使用 SqlAlchemy。 如果您没有安装,请执行以下操作:
$ sudo pip install Flask-SqlAlchemy
SQLAlchemy 是用于 Python 编程语言的 SQL 工具箱和对象关系映射器(ORM)。 它支持 MySQL,Microsoft SQL Server 和许多其他关系数据库管理系统。 如果您不熟悉所有这些术语,请继续阅读。
创建文件tabledef.py:
from sqlalchemy import *from sqlalchemy import create_engine, ForeignKeyfrom sqlalchemy import Column, Date, Integer, Stringfrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy.orm import relationship, backrefengine = create_engine('sqlite:///tutorial.db', echo=True)Base = declarative_base()########################################################################class User(Base):""""""__tablename__ = "users"id = Column(Integer, primary_key=True)username = Column(String)password = Column(String)#----------------------------------------------------------------------def __init__(self, username, password):""""""self.username = usernameself.password = password# create tablesBase.metadata.create_all(engine)
使用以下命令执行:
python tabledef.py
该文件将创建数据库结构。在目录内,您将找到一个名为tutorial.db的文件。创建一个名为dummy.py的文件,其中将包含以下代码:
import datetimefrom sqlalchemy import create_enginefrom sqlalchemy.orm import sessionmakerfrom tabledef import *engine = create_engine('sqlite:///tutorial.db', echo=True)# create a SessionSession = sessionmaker(bind=engine)session = Session()user = User("admin","password")session.add(user)user = User("python","python")session.add(user)user = User("jumpiness","python")session.add(user)# commit the record the databasesession.commit()session.commit()
执行:
$ python dummy.py
这会将伪数据放入数据库中。 最后,我们更新app.py
使用 SqlAlchemy 验证登录凭据
下一步是编写验证数据库中存在的用户和密码的功能。 使用 SqlAlchemy 我们可以做到这一点(虚拟/伪代码):
@app.route('/test')def test():POST_USERNAME = "python"POST_PASSWORD = "python"Session = sessionmaker(bind=engine)s = Session()query = s.query(User).filter(User.username.in_([POST_USERNAME]), User.password.in_([POST_PASSWORD]) )result = query.first()if result:return "Object found"else:return "Object not found " + POST_USERNAME + " " + POST_PASSWORD
我们使用 SqlAlchemys Oject 关系映射(ORM)。 我们将对象映射到关系数据库表,反之亦然。 定义(用户)在tabledef.py中给出。s.query函数是构建查询的地方。 我们有两个条件:用户名和密码必须匹配。 如果对象存在,query.first()返回true,否则返回false。 这给出了以下总代码:
from flask import Flaskfrom flask import Flask, flash, redirect, render_template, request, session, abortimport osfrom sqlalchemy.orm import sessionmakerfrom tabledef import *engine = create_engine('sqlite:///tutorial.db', echo=True)app = Flask(__name__)@app.route('/')def home():if not session.get('logged_in'):return render_template('login.html')else:return "Hello Boss! <a href="/logout">Logout</a>"@app.route('/login', methods=['POST'])def do_admin_login():POST_USERNAME = str(request.form['username'])POST_PASSWORD = str(request.form['password'])Session = sessionmaker(bind=engine)s = Session()query = s.query(User).filter(User.username.in_([POST_USERNAME]), User.password.in_([POST_PASSWORD]) )result = query.first()if result:session['logged_in'] = Trueelse:flash('wrong password!')return home()@app.route("/logout")def logout():session['logged_in'] = Falsereturn home()if __name__ == "__main__":app.secret_key = os.urandom(12)app.run(debug=True,host='0.0.0.0', port=4000)
现在,您可以使用数据库表中定义的任何用户登录。
那么安全性呢?
我们在上面演示了一个简单的登录应用程序。 但是,正确保护它是您的工作。 有很多人会尝试闯入您的应用程序。
最佳做法:
