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 win32 简单操作方法
May 25 Python
全面分析Python的优点和缺点
Feb 07 Python
python搭建服务器实现两个Android客户端间收发消息
Apr 12 Python
查找python项目依赖并生成requirements.txt的方法
Jul 10 Python
python实现彩票系统
Jun 28 Python
python爱心表白 每天都是浪漫七夕!
Aug 18 Python
浅析python3字符串格式化format()函数的简单用法
Dec 07 Python
Python openpyxl 遍历所有sheet 查找特定字符串的方法
Dec 10 Python
eclipse创建python项目步骤详解
May 10 Python
numpy中的ndarray方法和属性详解
May 27 Python
Python如何使用input函数获取输入
Aug 06 Python
python pillow库的基础使用教程
Jan 13 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的宝库目录--PEAR
2006/10/09 PHP
PHP 5.0对象模型深度探索之类的静态成员
2008/03/27 PHP
php中使用addslashes函数报错问题的解决方法
2013/02/06 PHP
php实现图片转换成ASCII码的方法
2015/04/03 PHP
从零开始学习jQuery (二) 万能的选择器
2010/10/01 Javascript
JavaScript设计模式之外观模式介绍
2014/12/28 Javascript
jquery插件tytabs.jquery.min.js实现渐变TAB选项卡效果
2015/08/25 Javascript
利用AngularJs实现京东首页轮播图效果
2016/09/08 Javascript
微信公众平台开发教程(五)详解自定义菜单
2016/12/02 Javascript
angular 用拦截器统一处理http请求和响应的方法
2017/06/08 Javascript
浅谈vue的几种绑定变量的值 防止其改变的方法
2018/03/01 Javascript
详解JavaScript的BUG和错误
2018/05/07 Javascript
vue项目前端微信JSAPI与外部H5支付相关实现过程及常见问题
2020/04/14 Javascript
Python 字符串中的字符倒转
2008/09/06 Python
Python语言实现获取主机名根据端口杀死进程
2016/03/31 Python
Python 中的with关键字使用详解
2016/09/11 Python
对Tensorflow中的变量初始化函数详解
2018/07/27 Python
Python简单获取二维数组行列数的方法示例
2018/12/21 Python
python 实现按对象传值
2019/12/26 Python
Python模块_PyLibTiff读取tif文件的实例
2020/01/13 Python
TensorFlow自定义损失函数来预测商品销售量
2020/02/05 Python
如何打包Python Web项目实现免安装一键启动的方法
2020/05/21 Python
浅谈keras通过model.fit_generator训练模型(节省内存)
2020/06/17 Python
使用Python文件读写,自定义分隔符(custom delimiter)
2020/07/05 Python
世界上最大的艺术社区:SAA
2020/12/30 全球购物
老公给老婆的道歉信
2014/01/10 职场文书
师范学院美术系毕业生自我鉴定
2014/01/29 职场文书
前厅收银主管岗位职责
2014/02/04 职场文书
工作目标责任书
2014/07/23 职场文书
小学生我的梦想演讲稿
2014/08/21 职场文书
回门宴新娘答谢词
2015/09/29 职场文书
《月球之谜》教学反思
2016/02/20 职场文书
React Hook用法示例详解(6个常见hook)
2021/04/28 Javascript
使用@Value值注入及配置文件组件扫描
2021/07/09 Java/Android
深入理解go缓存库freecache的使用
2022/02/15 Golang
戴尔Win11系统no bootable devices found解决教程
2022/09/23 数码科技