用Flask框架实现用户登录相对简单一些,可以用flask_login模块。
下面笔者亲测通过,就是登录写的太简单了:
没有做账号重复性验证,没有密码复杂性验证,没有写手机登录验证码校验模块,没有写图片验证码模块,没有做密码加盐加密,没有做前后端分离的token secure登录验证,没有做ssl,没有存session或cookie,没有做反爬虫处理。有兴趣的童鞋可以自行尝试。
说明:
本文代码在pycharm2018 + python3.6 + Flask + Mysql5.7下实现。
为了快速实现题主效果,参照了部分网络代码。
----------------------------------------
代码结构如下:
安装flask依赖包国内镜像(原始pip镜像在国外,下载安装模块极慢,且容易read timeout):
pip install flask --index https://pypi.mirrors.ustc.edu.cn/simple/
pip install flask_login --index https://pypi.mirrors.ustc.edu.cn/simple/
pip install flask_sqlalchemy --index https://pypi.mirrors.ustc.edu.cn/simple/
创建MySQL数据库用户表tb_user:
CREATE TABLE `tb_user` (
`user_id` int(11) NOT NULL AUTO_INCREMENT,
`account_number` varchar(45) CHARACTER SET utf8 COLLATE utf8_czech_ci NULL DEFAULT NULL,
`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_czech_ci NULL DEFAULT NULL,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_czech_ci NULL DEFAULT NULL,
PRIMARY KEY (`user_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_czech_ci ROW_FORMAT = Dynamic;
公共页面templates\base.html:
{% block title %}{% endblock %}{% block head %}{% endblock %}
{% block content %}{% endblock %}
登录页面templates\login.html:
{% extends "base.html" %}
{% block title %}python flask user page{% endblock %}
{% block head %}
{% endblock %}
{% block content %}
{% if form.errors %}
{% for name, errors in form.errors.items() %}
{% for error in errors %}
{{ error }}{% endfor %}
{% endfor %}
{% endif %}
账号:{{ form.account_number(size=20) }}{{ form.account_number.errors[0] }}
密码:
{{ form.hidden_tag() }}
登录
{% endblock %}
登录成功页面templates\index.html:
{% extends "base.html" %}
欢迎登录{% block content %}
登录成功,欢迎 {{ user.name }}!
{% endblock %}
js组件static\js\jquery-3.5.1.min.js:
下载地址:https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.5.1.min.jsajax.aspnetcdn.com
根目录下,Flask项目配置文件config.py:
DEBUG = True
SQLALCHEMY_ECHO = True
SQLALCHEMY_TRACK_MODIFICATIONS=True
# mysql+pymysql://数据用户名:数据库密码@数据库主机名或IP/数据库schema?charset=字符集
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:xxxxx@localhost/login_demo?charset=utf8'
SECRET_KEY = '79537d00f4834892986f09a100aa1edf'
数据库初始化文件common/__init__.py:
# config=utf-8
from flask_sqlalchemy import SQLAlchemy
__all__ = ['db']
db = SQLAlchemy()
数据库配置文件common/db_config.py:
# config=utf-8
from sqlalchemy import create_engine
from sqlalchemy.sql import text
from config import SQLALCHEMY_DATABASE_URI, SQLALCHEMY_ECHO
def db_query(sql, settings=None, echo=None):
if settings is None:
settings = SQLALCHEMY_DATABASE_URI
if echo is None:
echo = SQLALCHEMY_ECHO
return create_engine(settings, echo=echo).connect().execute(text(sql)).fetchall()
def db_execute(sql, settings=None, echo=None):
if settings is None:
settings = SQLALCHEMY_DATABASE_URI
if echo is None:
echo = SQLALCHEMY_ECHO
return create_engine(settings, echo=echo).connect().execute(text(sql)).rowcount
配置登录表单文件form/login_form.py:
# config=utf-8
from flask_wtf import FlaskForm as Form
from wtforms import StringField, PasswordField
from wtforms.validators import DataRequired
class LoginForm(Form):
account_number = StringField('account_number', validators=[DataRequired('account_number is null')])
password = PasswordField('password', validators=[DataRequired('password is null')])
用户model文件的初始化文件model/__init__.py:
# config=utf-8
from flask import Flask
from flask_login import LoginManager
from common import db
login_manager = LoginManager()
login_manager.login_view = "user.login"
def create_app(config_filename=None):
app = Flask(__name__)
login_manager.init_app(app)
if config_filename is not None:
app.config.from_pyfile(config_filename)
configure_database(app)
return app
def configure_database(app):
db.init_app(app)
用户model文件model/user_model.py:
# config=utf-8
from flask_login import UserMixin
from flask_login._compat import unicode
from common import db
class User(db.Model, UserMixin):
user_id = db.Column('user_id', db.Integer, primary_key=True)
account_number = db.Column(db.String(200), unique=True)
password = db.Column(db.String(50), unique=True)
name = db.Column(db.String(20), unique=True)
__tablename__ = 'tb_user'
def __init__(self, user_id=None, account_number=None, password=None, name="anonymous"):
self.user_id = user_id
self.account_number = account_number
self.password = password
self.name = name
def is_authenticated(self):
return True
def is_active(self):
return True
def is_anonymous(self):
return False
def get_id(self):
return unicode(self.user_id)
def __repr__(self):
return '' % (self.account_number)
用户登录跳转逻辑login.py:
# encoding:utf-8
# !/usr/bin/env python
from flask import render_template, request, redirect, Flask, Blueprint
from flask_login import login_user, login_required
from model.user_model import User
from model import login_manager
from form.login_form import LoginForm
userRoute = Blueprint('user', __name__, url_prefix='/user', template_folder='templates', static_folder='static')
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
@userRoute.before_request
def before_request():
pass
@userRoute.route('/success')
@login_required
def index():
return render_template('index.html')
@userRoute.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if request.method == 'POST':
if not form.validate_on_submit():
print(form.errors)
return render_template('login.html', form=form)
user = User.query.filter(User.account_number == form.account_number.data,
User.password == form.password.data).first()
if user:
login_user(user)
return render_template('index.html', user=user)
return render_template('login.html', form=form)
启动python flask服务文件run.py:
# config=utf-8
from login import userRoute
from model import create_app
DEFAULT_MODULES = [userRoute]
app = create_app('../config.py')
for module in DEFAULT_MODULES:
app.register_blueprint(module)
@app.before_request
def before_request():
pass
if __name__ == '__main__':
app.run(debug=True)
数据库手动插入一条记录:
执行run.py结果: