Flask框架的学习与实战(三):登陆管理
继续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-\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/
Flask框架的学习与实战(三):登陆管理的更多相关文章
- Flask框架的学习与实战(二):实战小项目
昨天写了一篇flask开发环境搭建,今天继续,进行一个实战小项目-blog系统. blog系统很简单,只有一个页面,然而麻雀虽小五脏俱全.这里目的不是为了做项目而做项目,这篇文章本意是通过这次练习传达 ...
- Flask框架的学习与实战(一):开发环境搭建
Flask是一个使用 Python 编写的轻量级 Web 应用框架.其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2.很多功能的实现都参考了django框架.由于项目需要,在 ...
- Flask框架从入门到实战
Flask简介: Flask是一个使用 Python 编写的轻量级 Web 应用框架,基于 WerkzeugWSGI工具箱和 Jinja2模板引擎.使用 BSD 授权. Flask也被称为 " ...
- flask框架的学习
---恢复内容开始--- 第一个flask程序讲解:1. 第一次创建项目的时候,要添加flask的虚拟环境.添加虚拟环境的时候,一定要选择到python这个执行文件.比如你的flask的虚拟环境的目录 ...
- Java框架spring 学习笔记(三):Bean 的生命周期
当一个 bean 被实例化时,它可能需要执行一些初始化使它转换成可用状态.当bean不再需要,并且从容器中移除时,需要做一些清除工作.为了定义安装和拆卸一个 bean,我们只要声明init-metho ...
- struts2学习之旅三 权限管理和导航设计
1,权限管理的db设计和dao实现,尽量简单快速有效: db的设计如下:权限按照角色来赋给用户: 权限对应每一个具体的功能,有菜单级别的,有导航级别的,还有页面级别的功能: 涉及到权限的敏感操作一般都 ...
- flask框架(十二):上下文管理***
情况一:单进程单线程 基于全局变量实现. 情况二:单进程多线程 基于threading.local对象. threading.local对象,用于为每个线程开辟一块空间来保存它独有的值. # -*- ...
- 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring事务管理接口PlatformTransactionManager、TransactionDefinition和TransactionStatus
Spring 的事务管理是基于 AOP 实现的,而 AOP 是以方法为单位的.Spring 的事务属性分别为传播行为.隔离级别.只读和超时属性,这些属性提供了事务应用的方法和描述策略. 在 Java ...
- Flask框架2
Flask框架的学习与实战(二):实战小项目 昨天写了一篇flask开发环境搭建,今天继续,进行一个实战小项目-blog系统. blog系统很简单,只有一个页面,然后麻雀虽小五脏俱全.这里目的不是 ...
随机推荐
- CentOS7网络桥接模式下配置-经典完备
原文地址:http://blog.csdn.net/youzhouliu/article/details/51175364 首先要将Vmware设置为桥接模式: 并选择宿主机连接的网路进行桥接: Ce ...
- Android中ProgressBar
ProgressBar提供如下方法来操作进度: setProgress(int):设置进度完成的百分比; incrementProgressBy(int):设置进度条的进度的增加或减少,具体取决于参数 ...
- mysql临时表空间暴涨
(此文刚好遇到转载记录) 一.内部临时表使用 在某些情况下,服务器在处理语句时创建内部临时表,而用户无法直接控制临时表何时发生,完全有MySQL内部自行决定. MySQL在以下几种情况会创建临时表: ...
- 搭建Squid反向代理服务器
好吧,更新个文章,有段时间没写技术博文了.今天就说说squid反向代理这个服务,当然,这是在Linux下配置完成的.说自己没偏见似乎不可能 了.大概是相对喜欢Linux而已.但我从不否认Windows ...
- k8s集群日志
硬件环境: 三台虚拟机, 10.10.20.203 部署docker.etcd.flannel.kube-apiserver.kube-controller-manager.kube-schedule ...
- MySQL视图概述
1.介绍 在传统关系型数据库里,视图有时也被称作虚表,是基于特定SQL结果集的虚拟数据表.在有些场合会变得很方便,例如:原有系统重构,旧的数据表A和B已经被拆分和合并到数据表C.D.F里面,为了实现平 ...
- Maven项目Update Project...后JRE System Library会自动变回1.5解决办法
<build> <finalName>pay</finalName> <plugins> <plugin> <groupId>o ...
- unittest 结合 ddt
数据驱动测试ddt,使用的重点: 1.@ddt.ddt2.@ddt.data(*zip(range(10),range(10,20))) 注意一定要带* 3.@ddt.unpack # c ...
- cnn 实例
http://www.geekcome.com/content-10-3761-1.html http://www.geekcome.com/content-10-3761-1.html http:/ ...
- angualejs
http://segmentfault.com/a/1190000000347412 http://www.xker.com/page/e2015/06/199141.html http://www. ...