Flask框架通过Flask_login实现用户登录功能示例


Posted in Python onJuly 17, 2018

本文实例讲述了Flask框架通过Flask_login实现用户登录功能。分享给大家供大家参考,具体如下:

通过Flask_Login实现用户验证登录,并通过login_required装饰器来判断用户登录状态来判断是否允许访问视图函数。

运行环境:

python3.5
Flask 0.12.2
Flask_Login 0.4.1
Flask-WTF 0.14.2
PyMySQL 0.8.0
WTForms 2.1
DBUtils 1.2

目录结构:

Flask框架通过Flask_login实现用户登录功能示例

直接看代码,具体功能有注释

Model/User_model.py

#创建一个类,用来通过sql语句查询结果实例化对象用
class User_mod():
 def __init__(self):
  self.id=None
  self.username=None
  self.task_count=None
  self.sample_count=None
 def todict(self):
  return self.__dict__
#下面这4个方法是flask_login需要的4个验证方式
 def is_authenticated(self):
  return True
 def is_active(self):
  return True
 def is_anonymous(self):
  return False
 def get_id(self):
  return self.id
 # def __repr__(self):
 #  return '<User %r>' % self.username

templates/login.html

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
</head>
<body>
 <div class="login-content">
  <form class="margin-bottom-0" action="{{ action }}" method="{{ method }}" id="{{ formid }}">
   {{ form.hidden_tag() }}
   <div class="form-group m-b-20">
    {{ form.username(class='form-control input-lg',placeholder = "用户名") }}
   </div>
   <div class="form-group m-b-20">
    {{ form.password(class='form-control input-lg',placeholder = "密码") }}
   </div>
   <div class="checkbox m-b-20">
    <label>
     {{ form.remember_me() }} 记住我
    </label>
   </div>
   <div class="login-buttons">
    <button type="submit" class="btn btn-success btn-block btn-lg">登 录</button>
   </div>
  </form>
 </div>
</body>
</html>

User_dal/dal.py

import pymysql
from DBUtils.PooledDB import PooledDB
POOL = PooledDB(
 creator=pymysql, # 使用链接数据库的模块
 maxconnections=6, # 连接池允许的最大连接数,0和None表示不限制连接数
 mincached=2, # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
 maxcached=5, # 链接池中最多闲置的链接,0和None不限制
 maxshared=3,
 # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
 blocking=True, # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
 maxusage=None, # 一个链接最多被重复使用的次数,None表示无限制
 setsession=[], # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
 ping=0,
 # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
 host='192.168.20.195',
 port=3306,
 user='root',
 password='youpassword',
 database='mytest',
 charset='utf8'
)
class SQLHelper(object):
 @staticmethod
 def fetch_one(sql,args):
  conn = POOL.connection() #通过连接池链接数据库
  cursor = conn.cursor() #创建游标
  cursor.execute(sql, args) #执行sql语句
  result = cursor.fetchone() #取的sql查询结果
  conn.close() #关闭链接
  return result
 @staticmethod
 def fetch_all(self,sql,args):
  conn = POOL.connection()
  cursor = conn.cursor()
  cursor.execute(sql, args)
  result = cursor.fetchone()
  conn.close()
  return result

User_dal/user_dal.py

from Model import User_model
from User_dal import dal
from User_dal import user_dal
class User_Dal:
 persist = None
 #通过用户名及密码查询用户对象
 @classmethod
 def login_auth(cls,username,password):
  print('login_auth')
  result={'isAuth':False}
  model= User_model.User_mod() #实例化一个对象,将查询结果逐一添加给对象的属性
  sql ="SELECT id,username,sample_count,task_count FROM User WHERE username ='%s' AND password = '%s'" % (username,password)
  rows = user_dal.User_Dal.query(sql)
  print('查询结果>>>',rows)
  if rows:
   result['isAuth'] = True
   model.id = rows[0]
   model.username = rows[1]
   model.sample_count = rows[2]
   model.task_count = rows[3]
  return result,model
 #flask_login回调函数执行的,需要通过用户唯一的id找到用户对象
 @classmethod
 def load_user_byid(cls,id):
  print('load_user_byid')
  sql="SELECT id,username,sample_count,task_count FROM User WHERE id='%s'" %id
  model= User_model.User_mod() #实例化一个对象,将查询结果逐一添加给对象的属性
  rows = user_dal.User_Dal.query(sql)
  if rows:
   result = {'isAuth': False}
   result['isAuth'] = True
   model.id = rows[0]
   model.username = rows[1]
   model.sample_count = rows[2]
   model.task_count = rows[3]
  return model
 #具体执行sql语句的函数
 @classmethod
 def query(cls,sql,params = None):
  result =dal.SQLHelper.fetch_one(sql,params)
  return result

denglu.py  flask主运行文件

from flask import Flask,render_template,redirect
from flask_login import LoginManager,login_user,login_required,current_user
from flask_wtf.form import FlaskForm
from wtforms import StringField, PasswordField, BooleanField
from wtforms.validators import Length,DataRequired,Optional
from User_dal import user_dal
app = Flask(__name__)
#项目中设置flask_login
login_manager = LoginManager()
login_manager.init_app(app)
app.config['SECRET_KEY'] = '234rsdf34523rwsf'
#flask_wtf表单
class LoginForm(FlaskForm):
 username = StringField('账户名:', validators=[DataRequired(), Length(1, 30)])
 password = PasswordField('密码:', validators=[DataRequired(), Length(1, 64)])
 remember_me = BooleanField('记住密码', validators=[Optional()])
@app.route('/login',methods=['GET','POST'])
def login():
 form = LoginForm()
 if form.validate_on_submit():
  username = form.username.data
  password = form.password.data
  result = user_dal.User_Dal.login_auth(username,password)
  model=result[1]
  if result[0]['isAuth']:
   login_user(model)
   print('登陆成功')
   print(current_user.username) #登录成功之后可以用current_user来取该用户的其他属性,这些属性都是sql语句查来并赋值给对象的。
   return redirect('/t')
  else:
   print('登陆失败')
   return render_template('login.html',formid='loginForm',action='/login',method='post',form=form)
 return render_template('login.html',formid='loginForm',action='/login',method='post',form=form)
'''登录函数,首先实例化form对象
然后通过form对象验证post接收到的数据格式是否正确
然后通过login_auth函数,用username与password向数据库查询这个用户,并将状态码以及对象返回
判断状态码,如果正确则将对象传入login_user中,然后就可以跳转到正确页面了'''
@login_manager.user_loader
def load_user(id):
 return user_dal.User_Dal.load_user_byid(id)
'''
load_user是一个flask_login的回调函数,在登陆之后,每访问一个带Login_required装饰的视图函数就要执行一次,
该函数返回一个用户对象,通过id来用sql语句查到的用户数据,然后实例化一个对象,并返回。
'''
#登陆成功跳转的视图函数
@app.route('/t')
@login_required
def hello_world():
 print('登录跳转')
 return 'Hello World!'
#随便写的另一个视图函数
@app.route('/b')
@login_required
def hello():
 print('视图函数b')
 return 'Hello b!'
if __name__ == '__main__':
 app.run()

简单总结一下:

通过flask的form表单验证数据格式
然后通过用户名密码从数据库取用户对象,将sql执行结果赋值给一个实例化的对象
将这个对象传给login_user,
然后成功跳转。
注意要写一个load_user回调函数吗,返回的是通过id取到的数据库并实例化的对象的用户对象。
这个回调函数每次访问带login_required装饰器的视图函数都会被执行。
还有一个就是current_user相当于就是实例化的用户对象,可以取用户的其他属性,注意,其他属性仅限于sql语句查到的字段并添加给实例化对象的属性。

代码比较简单,只是为了实现功能,敬请谅解,如有错误欢迎指出。

更多关于Python相关内容可查看本站专题:《Python入门与进阶经典教程》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》及《Python文件与目录操作技巧汇总》

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
详解Python如何获取列表(List)的中位数
Aug 12 Python
对python中return和print的一些理解
Aug 18 Python
Python操作mongodb的9个步骤
Jun 04 Python
pycharm创建一个python包方法图解
Apr 10 Python
Python pandas.DataFrame调整列顺序及修改index名的方法
Jun 21 Python
python Web flask 视图内容和模板实现代码
Aug 23 Python
浅析python内置模块collections
Nov 15 Python
浅析pip安装第三方库及pycharm中导入第三方库的问题
Mar 10 Python
在python3.64中安装pyinstaller库的方法步骤
Jun 02 Python
Python+kivy BoxLayout布局示例代码详解
Dec 28 Python
Python 图片处理库exifread详解
Feb 25 Python
Python与C++中梯度方向直方图的实现
Mar 17 Python
pycharm远程linux开发和调试代码的方法
Jul 17 #Python
Flask框架各种常见装饰器示例
Jul 17 #Python
详解基于django实现的webssh简单例子
Jul 17 #Python
Python爬虫之网页图片抓取的方法
Jul 16 #Python
python编辑用户登入界面的实现代码
Jul 16 #Python
python 反向输出字符串的方法
Jul 16 #Python
解决python3 urllib 链接中有中文的问题
Jul 16 #Python
You might like
PHP fgetcsv 定义和用法(附windows与linux下兼容问题)
2012/05/29 PHP
使用Post提交时须将空格转换成加号的解释
2013/01/14 Javascript
JavaScript设计模式之外观模式介绍
2014/12/28 Javascript
jQuery插件之Tocify动态节点目录菜单生成器附源码下载
2016/01/08 Javascript
一些实用性较高的js方法
2016/04/19 Javascript
Web前端新人笔记之jquery入门心得(新手必看)
2016/05/17 Javascript
正则表达式(语法篇推荐)
2016/06/24 Javascript
值得学习的bootstrap fileinput文件上传工具
2016/11/08 Javascript
走进javascript——不起眼的基础,值和分号
2017/02/24 Javascript
详解Vue.js分发之作用域槽
2017/06/13 Javascript
如何为你的JS项目添加智能提示与类型检查详解
2019/03/12 Javascript
vue和H5 draggable实现拖拽并替换效果
2020/07/29 Javascript
[04:22]DOTA2上海特级锦标赛主赛事第四日TOP10
2016/03/06 DOTA
用python实现百度翻译的示例代码
2018/03/09 Python
Python安装图文教程 Pycharm安装教程
2018/03/27 Python
Python中应该使用%还是format来格式化字符串
2018/09/25 Python
python遍历文件夹找出文件夹后缀为py的文件方法
2018/10/21 Python
opencv实现图片模糊和锐化操作
2018/11/19 Python
解决python给列表里添加字典时被最后一个覆盖的问题
2019/01/21 Python
Python中Numpy ndarray的使用详解
2019/05/24 Python
Python+numpy实现矩阵的行列扩展方式
2019/11/29 Python
使用python-opencv读取视频,计算视频总帧数及FPS的实现
2019/12/10 Python
Python常用编译器原理及特点解析
2020/03/23 Python
keras 指定程序在某块卡上训练实例
2020/06/22 Python
html5拍照功能实现代码(htm5上传文件)
2013/12/11 HTML / CSS
Betsey Johnson官网:妖娆可爱的连衣裙及鞋子、手袋和配件
2016/12/30 全球购物
写一个用矩形法求定积分的通用函数
2012/11/08 面试题
客户表扬信范文
2014/01/10 职场文书
九年级历史教学反思
2014/01/27 职场文书
个人对照检查材料思想汇报
2014/09/26 职场文书
家属慰问信
2015/02/14 职场文书
消防隐患整改通知书
2015/04/22 职场文书
2015年度个人工作总结报告
2015/10/24 职场文书
导游词之山海关
2019/12/10 职场文书
Python使用MapReduce进行简单的销售统计
2022/04/22 Python
Win11自动黑屏怎么办 Win11自动黑屏设置教程
2022/07/15 数码科技