Flask框架的学习指南之用户登录管理


Posted in Python onNovember 20, 2016

继续flask的学习之旅。今天介绍flask的登陆管理模块,还记得上一篇中的blog小项目么,登录是咱们自己写的验证代码,大概有以下几个步骤:

1、在登录框中输入用户名和密码

2、flask view函数获取用户密码,然后到数据库中查询该用户信息,进行匹配

3、如果成功,就写入session中,重定向到首页

4、如果对于特定视图,必须要登录才能访问,那么需要在每个视图函数验证session里是否存在该用户。

今天继续改造blog项目,介绍的flask-login模块就是替我们来搞定这些业务相关度较少的公用功能,它可以帮助我们:

在会话中存储当前活跃的用户 ID,让你能够自由地登入和登出。
让你限制登入(或者登出)用户可以访问的视图。
处理让人棘手的 “记住我” 功能。
帮助你保护用户会话免遭 cookie 被盗的牵连。
可以与以后可能使用的 Flask-Principal 或其它认证扩展集成。

一、如何使用flask-login模块?

1、安装flask-login

E:\workdir\dct-server-5055187\src>pip install flask-login

2、使用flask-login

 2.1)  在/blog2/__init__.py添加:

#引用包
from flask.ext.login import LoginManager

#登陆管理
#声明login对象
login_manager = LoginManager()
#初始化绑定到应用
login_manager.init_app(app)

#声明默认视图函数为login,当我们进行@require_login时,如果没登陆会自动跳到该视图函数处理
login_manager.login_view = "login"

#当登陆成功后,该函数会自动从会话中存储的用户 ID 重新加载用户对象。它应该接受一个用户的 unicode ID 作为参数,并且返回相应的用户对象。
@login_manager.user_loader
def load_user(userid):
return User.query.get(int(userid))

2.2) 修改User模型(红色部分为新增代码)

from flask.ext.login import UserMixin

from blog2 import db

class User(db.Model, UserMixin):
  __tablename__ = 'b_user'
  id = db.Column(db.Integer,primary_key=True)
  username = db.Column(db.String(10),unique=True)
  password = db.Column(db.String(16))

  def __init__(self,username,password):
    self.username = username
    self.password = password
  def __repr__(self):
    return '<User %r>' % self.username

该用户类必须实现以下几个方法:

is_authenticated

当用户通过验证时,也即提供有效证明时返回 True(只有通过验证的用户会满足 login_required 的条件。)

is_active

如果这是一个活动用户且通过验证,账户也已激活,未被停用,也不符合任何你 的应用拒绝一个账号的条件,返回 True 。不活动的账号可能不会登入(当然, 是在没被强制的情况下)。

is_anonymous

如果是一个匿名用户,返回 True 。(真实用户应返回 False 。)

get_id()

返回一个能唯一识别用户的,并能用于从 user_loader 回调中加载用户的 unicode 。注意着 必须 是一个 unicode —— 如果 ID 原本是 一个 int 或其它类型,你需要把它转换为 unicode 。
要简便地实现用户类,你可以从 UserMixin 继承,它提供了对所有这些方法的默认实现。我们这里使用UserMixin实现。

2.3) 修改view函数(红色部分为新增)

from flask.ext.login import login_required, login_user, logout_user

from blog2.model.User import User
from blog2.model.Category import Category
import os

from blog2 import app,db
from flask import request,render_template,flash,abort,url_for,redirect,session,Flask,g

@app.route('/')
@login_required
def show_entries():
  categorys = Category.query.all()
  return render_template('show_entries.html',entries=categorys)

@app.route('/add',methods=['POST'])
@login_required
def add_entry():
  #——————————————————————————————————————————————
  # 第一版登陆方式
  # if not session.get('logged_in'):
  #   abort(401)
  #——————————————————————————————————————————————

  title = request.form['title']
  content = request.form['text']
  category = Category(title,content)
  db.session.add(category)
  db.session.commit()
  flash('New entry was successfully posted')
  return redirect(url_for('show_entries'))

@app.route('/login',methods=['GET','POST'])
def login():
  error = None
  if request.method == 'POST':
    user = User.query.filter_by(username=request.form['username']).first()
    #——————————————————————————————————————————————————————————————————————————
    #第一版登陆方式
    # passwd = User.query.filter_by(password=request.form['password']).first()
    #
    # if user is None:
    #   error = 'Invalid username'
    # elif passwd is None:
    #   error = 'Invalid password'
    # else:
    #   session['logged_in'] = True
    #   flash('You were logged in')
    #   return redirect(url_for('show_entries'))
    #——————————————————————————————————————————————————————————————————————————

    login_user(user)
    flash('Logged in successfully.')
    return redirect(url_for('show_entries'))

  return render_template('login.html', error=error)

@app.route('/logout')
@login_required
def logout():
  #—————————————————————————————————————————————— 
  # 第一版登出方式
  # session.pop('logged_in', None)
  #—————————————————————————————————————————————— 
 logout_user()
  flash('You were logged out')
  return redirect(url_for('show_entries'))

通过flask-login管理登陆,代码非常简洁简单:

@login_required:该装饰器放到需要登陆才能访问的视图上,如果没有登陆访问有限制的视图就会跳到login页面,由__init__.py中login_manager.login_view = "login"控制
login_user(user):传入一个user对象进行登陆验证,正确返回true,否则返回false
logout_user():登出函数,清空session中用户信息

2.4) 模板中引用用户

{% if current_user.is_authenticated() %}
 Hi {{ current_user.name }}!
{% endif %}

将之前layout.html和show_entries.html模板中判断用户是否登陆方式改为flask-login中的方式:

{% if not current_user.is_authenticated() %}

current_user值:在用户没有登陆时,值为<flask_login.AnonymousUserMixin object at 0x0000000003DCF550>,也就是匿名用户
                用户登陆后,值为<User u'admin'>

当然,用户登陆还可以根据实际情况自己定制,具体不在一一详述。

【参考文档】

       Flask-Login中文版:http://www.pythondoc.com/flask-login/#id1
       Flask-Login英文版:http://flask-login.readthedocs.io/en/latest/

Python 相关文章推荐
利用Python实现Windows定时关机功能
Mar 21 Python
Python cookbook(数据结构与算法)同时对数据做转换和换算处理操作示例
Mar 23 Python
Python堆排序原理与实现方法详解
May 11 Python
详解python while 函数及while和for的区别
Sep 07 Python
pyinstaller打包单个exe后无法执行错误的解决方法
Jun 21 Python
Python搭建Keras CNN模型破解网站验证码的实现
Apr 07 Python
Python 保存加载mat格式文件的示例代码
Aug 04 Python
一篇文章搞懂python的转义字符及用法
Sep 03 Python
Pytest单元测试框架如何实现参数化
Sep 05 Python
linux centos 7.x 安装 python3.x 替换 python2.x的过程解析
Dec 14 Python
python基础详解之if循环语句
Apr 24 Python
详解NumPy中的线性关系与数据修剪压缩
May 25 Python
Flask框架的学习指南之制作简单blog系统
Nov 20 #Python
Flask框架的学习指南之开发环境搭建
Nov 20 #Python
Python 描述符(Descriptor)入门
Nov 20 #Python
独特的python循环语句
Nov 20 #Python
【Python】Python的urllib模块、urllib2模块批量进行网页下载文件
Nov 19 #Python
Python基础中所出现的异常报错总结
Nov 19 #Python
轻松掌握python设计模式之策略模式
Nov 18 #Python
You might like
PHP魔术方法的使用示例
2015/06/23 PHP
PHP函数func_num_args用法实例分析
2015/12/07 PHP
详解js异步文件加载器
2016/01/24 PHP
thinkphp修改配置进入默认首页的方法
2017/02/07 PHP
PHP基于堆栈实现的高级计算器功能示例
2017/09/15 PHP
Laravel框架控制器的middleware中间件用法分析
2019/09/30 PHP
js实现DIV的一些简单控制
2007/06/04 Javascript
增强的 JavaScript 的 trim 函数的代码
2007/08/13 Javascript
jquery 查找select ,并触发事件的实现代码
2011/03/30 Javascript
js函数在frame中的相互调用详解
2014/03/03 Javascript
Javascript图片上传前的本地预览实例
2014/06/16 Javascript
JavaScript lastIndexOf方法入门实例(计算指定字符在字符串中最后一次出现的位置)
2014/10/17 Javascript
Javascript中的数组常用方法解析
2016/06/17 Javascript
JS获取鼠标选中的文字
2016/08/10 Javascript
完美解决spring websocket自动断开连接再创建引发的问题
2017/03/02 Javascript
ES7中利用Await减少回调嵌套的方法详解
2017/11/01 Javascript
让Vue也可以使用Redux的方法
2018/05/23 Javascript
Vue实现商品详情页的评价列表功能
2019/09/04 Javascript
vue中的使用token的方法示例
2020/03/10 Javascript
[56:00]DOTA2上海特级锦标赛主赛事日 - 4 胜者组决赛Secret VS Liquid第一局
2016/03/05 DOTA
[04:52]第二届DOTA2亚洲邀请赛主赛事第一天比赛集锦:OG娜迦海妖放大配合谜团大中3人
2017/04/02 DOTA
[05:03]2018DOTA2亚洲邀请赛主赛事首日回顾
2018/04/04 DOTA
[33:23]Secret vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
python插入数据到列表的方法
2015/04/30 Python
Python设计模式之工厂模式简单示例
2018/01/09 Python
用Python将结果保存为xlsx的方法
2019/01/28 Python
Pyqt5 基本界面组件之inputDialog的使用
2019/06/25 Python
python图形绘制奥运五环实例讲解
2019/09/14 Python
python爬虫添加请求头代码实例
2019/12/28 Python
python实现提取str字符串/json中多级目录下的某个值
2020/02/27 Python
Adobe Html5 Extension开发初体验图文教程
2017/11/14 HTML / CSS
意大利折扣和优惠券网站:Groupalia
2019/10/09 全球购物
营业员实习自我鉴定
2013/12/07 职场文书
运动会演讲稿50字
2014/08/25 职场文书
保研专家推荐信范文
2015/03/25 职场文书
法院执行局工作总结
2015/08/11 职场文书