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中使用logging模块打印log日志详解
Apr 05 Python
Python EOL while scanning string literal问题解决方法
Sep 18 Python
python使用Apriori算法进行关联性解析
Dec 21 Python
python进阶之多线程对同一个全局变量的处理方法
Nov 09 Python
Python 获取主机ip与hostname的方法
Dec 17 Python
Django MEDIA的配置及用法详解
Jul 25 Python
Pycharm和Idea支持的vim插件的方法
Feb 21 Python
python GUI库图形界面开发之PyQt5控件QTableWidget详细使用方法与属性
Feb 25 Python
python画图常规设置方式
Mar 05 Python
Python调用JavaScript代码的方法
Oct 27 Python
tensorflow2.0教程之Keras快速入门
Feb 20 Python
python实现局部图像放大
Nov 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扩展图文教程
2008/12/12 PHP
一个基于PDO的数据库操作类
2011/03/24 PHP
记录Yii2框架开发微信公众号遇到的问题及解决方法
2018/07/20 PHP
PHP常用函数之格式化时间操作示例
2019/10/21 PHP
一个很简单的jquery+xml+ajax的无刷新树结构(无css,后台是c#)
2010/06/02 Javascript
JavaScript实现三阶幻方算法谜题解答
2014/12/29 Javascript
可以浮动某个物体的jquery控件用法实例
2015/07/24 Javascript
jQuery使用$.each遍历json数组的简单实现方法
2016/04/18 Javascript
JS Canvas定时器模拟动态加载动画
2016/09/17 Javascript
整理一些最近经常遇到的前端面试题
2017/04/25 Javascript
原生js实现简单的模态框示例
2017/09/08 Javascript
认识jQuery的Promise的具体使用方法
2017/10/10 jQuery
jquery实现回车键触发事件(实例讲解)
2017/11/21 jQuery
小试小程序云开发(小结)
2019/06/06 Javascript
利用Vue-draggable组件实现Vue项目中表格内容的拖拽排序
2019/06/07 Javascript
如何使用Node.js爬取任意网页资源并输出PDF文件到本地
2019/06/17 Javascript
微信小程序实现页面分享onShareAppMessage
2019/08/12 Javascript
vue实现全屏滚动效果(非fullpage.js)
2020/03/07 Javascript
react实现复选框全选和反选组件效果
2020/08/25 Javascript
jQuery实现简单全选框
2020/09/13 jQuery
用Python进行基础的函数式编程的教程
2015/03/31 Python
Django框架下在URLconf中指定视图缓存的方法
2015/07/23 Python
Python利用前序和中序遍历结果重建二叉树的方法
2016/04/27 Python
python 自动批量打开网页的示例
2019/02/21 Python
Python3进制之间的转换代码实例
2019/08/24 Python
PyCharm 2020.2 安装详细教程
2020/09/25 Python
凯特·丝蓓英国官网:Kate Spade英国
2016/11/07 全球购物
FitFlop美国官网:英国符合人体工学的鞋类品牌
2018/10/05 全球购物
企业后勤岗位职责
2014/02/28 职场文书
校园活动宣传方案
2014/03/28 职场文书
爱国电影观后感
2015/06/19 职场文书
Go缓冲channel和非缓冲channel的区别说明
2021/04/25 Golang
Python打包exe时各种异常处理方案总结
2021/05/18 Python
详解Oracle数据库中自带的所有表结构(sql代码)
2021/11/20 Oracle
十大必看国产动漫排名,魁拔上线,第二曾在日本播出
2022/03/18 国漫
SpringBoot中使用Redis作为全局锁示例过程
2022/03/24 Java/Android