flask验证用户登录
from flask import Flask, flash, render_template, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin, login_required, LoginManager, login_user
from flask_wtf import FlaskForm
from wtforms.validators import DataRequired, Length
from wtforms import StringField, SubmitField, PasswordField
from flask_bootstrap import Bootstrap
from flask_migrate import Migrate
import os
base_dir = os.path.abspath(os.path.dirname(__file__))
app = Flask(__name__)
app.config['SECRET_KEY'] = "sdflk*()"
app.config['SQLALCHEMY_DATABASE_URI'] = \
'sqlite:///' + os.path.join(base_dir, 'data.sqlite')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
login_manager = LoginManager(app)
login_manager.login_view = 'login' # 设置登录页面的端点
bootstrap = Bootstrap(app)
migrate = Migrate(app, db)
class UserForm(FlaskForm):
username = StringField('username', validators=[DataRequired(), Length(5, 15)])
password = PasswordField('password', validators=[DataRequired(), Length(5, 15)])
submit = SubmitField('login')
class User(UserMixin , db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True)
password_hash = db.Column(db.String(128))
@property
def password(self):
'''设置密码的属性为只写,如果强行读取则返回错误'''
raise AttributeError('密码不能读取')
@password.setter
def password(self, password):
'''当类初始化时自动调用,把password的值转换为散列值'''
self.password_hash = generate_password_hash(password)
def verify_password(self, password) -> bool:
'''用于登录时验证密码'''
return check_password_hash(self.password_hash, password)
@login_manager.user_loader # 把函数注册给flask-login, 当flask-login要获取用户信息时调用
def load_user(id):
'''用于加载用户'''
return User.query.get(int(id))
@app.route("/login", methods=['GET', 'POST'])
def login():
form = UserForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user is not None:
if user.verify_password(form.password.data):
flash('登录成功')
login_user(user)# login_user的参数为要登录的用户,以及可选的"记住我"布尔值
return redirect(url_for('index'))
flash('登录失败')
return render_template('login.html', form=form)
@app.route("/")
@login_required # 用于保护路由,只允许登录过的用户访问
def index():
return render_template("index.html")
@app.shell_context_processor
def make_context_processor():
return dict(db=db, User=User)
if __name__ == "__main__":
app.run("0.0.0.0", 9999, True)
login.html
{% extends 'bootstrap/base.html' %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block content %}
<div class="container">
<div class="page-header">
<h1>Login</h1>
</div>
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<span class="label label-info">{{message}}</span><!-- 打印闪现消息-->
{% endfor %}
{% endif %}
{% endwith %}
<div class="col-xs-5 col-sm-5 col-md-5 col-lg-5">
{{ wtf.quick_form(form) }}
</div>
</div>
{% endblock content %}
index.html
{% extends 'bootstrap/base.html' %}
{% block content %}
<div class="container">
<div class="page-header">
<h1>Index</h1>
</div>
<p>登录成功</p>
</div>
{% endblock content %}