先看官方例子:

from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
from flask_security import Security, SQLAlchemyUserDatastore, \UserMixin, RoleMixin, login_required
# Create app
app = Flask(__name__)
app.config['DEBUG'] = True
app.config['SECRET_KEY'] = 'super-secret'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'
# Create database connection object
db = SQLAlchemy(app)
# Define models
roles_users = db.Table('roles_users',db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))
class Role(db.Model, RoleMixin):id = db.Column(db.Integer(), primary_key=True)name = db.Column(db.String(80), unique=True)description = db.Column(db.String(255))
class User(db.Model, UserMixin):id = db.Column(db.Integer, primary_key=True)email = db.Column(db.String(255), unique=True)password = db.Column(db.String(255))active = db.Column(db.Boolean())confirmed_at = db.Column(db.DateTime())roles = db.relationship('Role', secondary=roles_users,backref=db.backref('users', lazy='dynamic'))
# Setup Flask-Security
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)
# Create a user to test with
@app.before_first_request
def create_user():db.create_all()user_datastore.create_user(email='matt@nobien.net', password='password')db.session.commit()
# Views
@app.route('/')
@login_required
def home():return render_template('index.html')
if __name__ == '__main__':app.run()

使用 Flask-Security 创建User和Role

通过Flask-Security我们可以很方便的管理用户权限但是它对我们的model有一定的要求。请看下图:

扩展要求数据库必须要有User和Role这两张表以及包含相应的字段,Flask-Security才能够帮助我们生成权限管理的解决方案。举个简单的例子,通过使用Flask-Security, 我们可以用下面的方式创建用户:

from urls import db, User,  Role
from flask_security import SQLAlchemyUserDatastore, Security
# Setup Flask-Security
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)
db.create_all()
# 创建管理员
admin = user_datastore.create_user(email='admin@4paradigm.com', password='admin')
# 创建普通用户角色和Admin角色
user_role = user_datastore.create_role(name='User', description='Generic user role')
admin_role = user_datastore.create_role(name='Admin', description='Admin user role')
# 为admin添加Admin角色(admin_role)
user_datastore.add_role_to_user(admin, admin_role)db.session.commit()

上面是我初始化数据库的代码。使用SQLAlchemyUserDatastore来封装db, 使用Security封装我们的app。 然后创建用户和角色,并且使用add_role_to_user的方式为用户添加角色。Flask-Security为我们提供了很多有用的方法。请看下面的截图:

更多的API请查看官方文档:https://pythonhosted.org/Flask-Security/api.html

上面说的这些方法都可以很有效的管理我们数据库中User和Role的关系。

使用Flask-Security来做权限控制

角色保护

当我们拥有了用户和角色以后, 就可以很方便的使用Flask-Security的装饰器来保护我们的页面。比如 @roles_required('Admin')可以用来保护一个路由方法。只有当前用户拥有'Admin'的角色的时候才被准许访问。例如下面的使用方法:

@app.route('/config/save', methods=['POST'])
@roles_required('Admin')
def save_config():

注:roles_required这个装饰器一定要放在app.route下面。
当用户没有Admin权限的时候是无法访问这个路由方法的。它会通过flush函数像页面反馈错误信息。如下:

除了roles_required之外,你还可以使用roles_accepted。前者必须严格的拥有所指定的权限,后者是只要拥有其中一个权限就可以。如下:

@roles_accepted('editor', 'author')

意思是要求用户至少拥有这两种role其中的一种就可以访问。 除了使用装饰器以外,Flask-Security也支持以编码的方式控制权限。例如:

@app.route('/')@app.route('/index', methods=['GET', 'POST'])@login_requireddef index():if current_user.has_role('Admin'):names = Env.query.all()return render_template('index.html', names=names)else:names = current_user.envsreturn render_template('index.html', names=names)

current_user.has_role方法判断当前用户是属于哪一种角色(current_user是Flask-Security针对Flask-Login做的扩展,作用是在当前session中维护用户的信息)。关于Flask-Security提供的更多方法,请参照文档:https://pythonhosted.org/Flask-Security/api.html

Flask-Login

初始化Flask-Login
from flask_login import LoginManager
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'

使用LoginManager来初始化,并把login_view设置为login方法。 这是为了之后给登录保护使用的。当Flask-Login检测到用户没有登录的时候会把链接重定向到login_view中去。

登录

Flask-Security其实就是扩展了其他各种模块。想用它就必须安装其他模块,而且它的封装改变了其他模块的使用方式。 例如Flask-Login有login和logout方法,Flask-Security也有,你需要使用Flask-Security提供的方法进行登录和登出才能做好权限控制,因为原生的Flask-Loing无法保存User和Role相关的信息。你可以这么看待Flask-Security:它的作用就是封装了其他模块,它的底层其实也是调用的其他模块。 举个例子,当你想要做用户登录的时候。我们使用如下的方式:

from flask_security.utils import login_user, logout_user
@app.route('/user/register', methods=['GET', 'POST'])
def register():form = forms.RegisterForm()if form.validate_on_submit():if form.password.data != form.password_again.data:errors = '两次输入的密码不同'return render_template('register.html', form=form, errors=errors)new_user = user_datastore.create_user(email=form.email.data, password=form.password.data)normal_role = user_datastore.find_role('User')db.session.add(new_user)user_datastore.add_role_to_user(new_user, normal_role)login_user(new_user)return redirect(url_for('index'))return render_template('register.html', form=form)

这是用户注册的代码。表单验证通过后,使用Flask-Security的方法在数据库中创建用户信息,然后查找User角色,给用户添加为普通用户的权限。然后调用login_user方法进行登录。这里需要注意的是,import的是flask_security.utiles中的login_user方法而不是Flask-Login的。Flask-Security是封装了其他各种模块的存在,所以现在我们是完全使用Flask-Security的方式来进行登录。 登录以后,用户信息(也就是User对象)会自动的保存在session中。 可以通过引入current_user的方式获取当前的用户。如下:

from flask_security import  current_user
@app.route('/user/login', methods=['POST', 'GET'])
def login():if not current_user.is_anonymous:return redirect(url_for('index'))form = forms.LoginForm()if form.validate_on_submit():user = User.query.filter_by(email=form.email.data).first()if user is None:form.errors['username_error'] = 'user does not exit'return render_template('login.html', form=form)if not user.password == form.password.data:form.errors['password_error'] = 'password is not right'return render_template('login.html', form=form)login_user(user, remember=True)return redirect(url_for('index'))return render_template('login.html', form=form)

上面是登录的代码。import的仍然是Flask-Security的current_user而不是Flask-Login的。 先判断当前的user是不是匿名用户(未登录的就是匿名用户)。如果不是匿名用户,说明已经登录了,就重定向到首页。这里引用了current_user。它其实就是Flask-Security创建的User对象。它包含了所有的User对象的属性和方法。发现用户未登录后,首先判断是不是表单提交以及表单提交是否通过。如果通过了就从数据库中查询出用户的信息。 判断用户是否存在以及填写的密码是否正确。登录后,这个User对象就赋值给current_user了。 可以在模板页面中直接使用current_user。如下:

<div class="col-md-12 column"><h4>你好 {{ current_user.email }}            </h4></div>

Flask-Login自动会把current_user传递给模板页面,所以直接在页面引用就可以了。 把上面的代码写入到base.html,提取每个用户的邮箱。 并显示

登录保护

Flask-Security提供了roles_required这种装饰器来进行权限的保护。自然也就提供了login_required的装饰器来进行登录保护。如下:

@app.route('/user/logout')
@login_required
def logout():

当Flask发现用户并没有登录的时候,就会把链接重定向到我们一开始设置的login_view的页面上了。也就是登录页面。

尽量不要把Flask-Login的版本升级到0.4.0, 使用0.3.2就可以了。 因为Flask-Security在封装Flask-Login 0.4.0的时候会报一个找不到token_loader的错误。因为Flask-Login在0.4.0的时候已经不使用这个token了。

转载于:https://blog.51cto.com/wenguonideshou/1982232

Flask-Login Flask-Security 登录与权限控制相关推荐

  1. 动态参数 maven_Spring Security 动态url权限控制(三)

    一.前言 本篇文章将讲述Spring Security 动态分配url权限,未登录权限控制,登录过后根据登录用户角色授予访问url权限 基本环境 spring-boot 2.1.8 mybatis-p ...

  2. 传智健康_第9章 移动端开发-手机快速登录、权限控制

    传智健康_第9章 移动端开发-手机快速登录.权限控制 文章目录 传智健康_第9章 移动端开发-手机快速登录.权限控制 1. 需求分析 2. 手机快速登录 2.1 页面调整 2.1.1 发送验证码 2. ...

  3. 手工搭建基于ABP的框架(3) - 登录,权限控制与日志

    为了防止不提供原网址的转载,特在这里加上原文链接: http://www.cnblogs.com/skabyy/p/7695258.html 本篇将实现登录.权限控制.日志配置与审计日志的功能.首先我 ...

  4. OAuth2.0 原理流程及其单点登录和权限控制

    作者:王克锋 kefeng.wang/2018/04/06/oauth2-sso 单点登录是多域名企业站点流行的登录方式.本文以现实生活场景辅助理解,力争彻底理清 OAuth2.0 实现单点登录的原理 ...

  5. 傻瓜式使用SpringSecurity完成前后端分离+JWT+登录认证+权限控制

    流程分析 流程说明: 客户端发起一个请求,进入 Security 过滤器链.当到 LogoutFilter 的时候判断是否是登出路径,如果是登出路径则到 logoutHandler ,如果登出成功则到 ...

  6. 使用service实现登录、权限控制

    2019独角兽企业重金招聘Python工程师标准>>> 文章来源:http://blog.ddlisting.com 官网对于登录.用户权限的介绍只有一段简单的说明,并没有详细说明如 ...

  7. IdentityServer4实现Token登录以及权限控制

    相关知识点 不再对IdentityServer4做相关介绍,博客园上已经有人出了相关的系列文章,不了解的可以看一下: 蟋蟀大神的:小菜学习编程-IdentityServer4 晓晨Master:Ide ...

  8. spring boot系列03--spring security (基于数据库)登录和权限控制(下)

    (接上篇) 后台 先说一下AuthConfig.java Spring Security的主要配置文件之一 AuthConfig 1 @Configuration 2 @EnableWebSecuri ...

  9. java oauth sso 源码_基于Spring Security Oauth2的SSO单点登录+JWT权限控制实践

    概 述 在前文<基于Spring Security和 JWT的权限系统设计>之中已经讨论过基于 Spring Security和 JWT的权限系统用法和实践,本文则进一步实践一下基于 Sp ...

最新文章

  1. Apache-2.2.32安装配置
  2. .NET开发Windows Service程序 - Topshelf
  3. 如何实现MindManager数据库导入数据连接
  4. 【C语言】最大的两个数(指针专题)
  5. C语言 semaphore
  6. python pca双标图的含义_PCA双标图 - 箭长度
  7. 【愣锤笔记】能解决80%场景的Git必会知识点
  8. 安装程序检测到无法验证文件的发行者_文件的校验方法
  9. 图像处理与机器学习-第一章(概述)
  10. vue项目性能优化详解汇总
  11. 国际服务贸易重点整理
  12. java获取ip地址 方法_java获取IP地址的方法
  13. 准确率(accuracy)、召唤率(recall)和精确率(precision)、False Positive、True Positive、False Negative True Negativ的关系
  14. Attempted reconnect 3 times. Giving up
  15. 堆外内存(off-heap),堆内存(on-heap)
  16. 【转】微信小程序日期时间选择器(年月日时分秒)
  17. 【Java学习笔记】38.Java 发送邮件
  18. 多线程为什么会出现安全问题
  19. iTunes 备份损坏的解决办法
  20. ServiceHot ITSM助力天原集团IT运维信息化建设

热门文章

  1. 面试-设计模式六大原则
  2. 【热点报道】2013eoe移动开发者大会圆满落幕
  3. Cisco C2960 升级IOS
  4. maven+svn+hudson+weblogic构建持续集成环境
  5. 美工一流的个人网站源码系列(2),不漂亮你可以不下载!
  6. Python-3.7.0
  7. SecureCRTPortable - 破解
  8. WIN8 启用虚拟AP 以共享网络,使手机电脑一起网上冲浪
  9. Centos7 更新gcc版本
  10. 彻底卸载SqlServer2008R2