日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Flask权限管理

發(fā)布時間:2024/8/24 编程问答 28 如意码农
生活随笔 收集整理的這篇文章主要介紹了 Flask权限管理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

權(quán)限管理功能的實現(xiàn)可以分為以下幾個小塊:
1,新建數(shù)據(jù)庫表Role,里面包括id(Integer,主鍵)name(String),permission(Integer),default(boolean)。users是指向User模型的對外關(guān)系,反向賦給User模型一個role屬性,這樣就可以同郭User.role來訪問Role模型,這樣就創(chuàng)建了數(shù)據(jù)庫之間的關(guān)系。模型里面還定義了一個靜態(tài)方法(@staticmethod,可以直接通過類訪問這個方法而不需要創(chuàng)建實例之后才能訪問這個方法),它的作用是初始化Role數(shù)據(jù)表中的數(shù)據(jù),數(shù)據(jù)庫模型代碼如下:

class Role(db.Model):
# 定義Role的數(shù)據(jù)庫模型
__tablename__ = 'roles'
id = db.Column(db.Integer, primary_key=True)
# 該用戶角色名稱
name = db.Column(db.String(64), unique=True)
# 該用戶角色對應(yīng)的權(quán)限
permissions = db.Column(db.Integer)
# 該用戶角色是否為默認(rèn)
default = db.Column(db.Boolean, default=False, index=True)
# 角色為該用戶角色的所有用戶
users = db.relationship('User', backref='role', lazy='dynamic') @staticmethod
def insert_role():
roles = {
'STAFF': (Permission.ONLY_QUERY, True),
'HIGH_STAFF': (Permission.ONLY_QUERY|
Permission.FORBID, False),
'LEADER': (Permission.ONLY_QUERY|
Permission.FORBID|
Permission.ASSIGN, False),
'ADMINISTATOR': (0x0f, False)
}#除了onlyquery之外,其他的都是模式false
for r in roles:
role = Role.query.filter_by(name=r).first()
if role is None:
# 如果用戶角色沒有創(chuàng)建: 創(chuàng)建用戶角色
role = Role(name=r)
role.permissions = roles[r][0]
role.default = roles[r][1]
db.session.add(role)
db.session.commit() def __repr__(self):
return '<Role %r>' % self.name

Permission類代碼如下:

class Permission:
ONLY_QUERY = 0x01#僅查詢
FORBID = 0x03#封號
ASSIGN= 0x07#分配行號
ADMINISTRATOR = 0x0f#這個權(quán)限要異或

2,授予用戶權(quán)限:在User模型中添加role的屬性

class User(UserMixin,db.Model):
__tablename__ = 'users'
id = db.Column(db.SmallInteger,primary_key=True,nullable=False)#這個字段必須是id,否則無法完成登錄驗證
username = db.Column(db.String(64))
password_hash = db.Column(db.String(128))
email = db.Column(db.String(64))
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
config_content = config[os.getenv('FLASK_CONFIG') or 'default']

因為User模型有role的屬性,可以通過User.role來獲取Role數(shù)據(jù)庫中的內(nèi)容,所以我們的思路是直接通過這一特性進行操作,直接在User模型中的初始化方法中實現(xiàn)默認(rèn)權(quán)限的賦予,是管理員給管理員權(quán)限,不是給默認(rèn)的用戶權(quán)限。

    def  __init__(self,**kwargs):
super(User,self).__init__(**kwargs)
#繼承了父類的初始化方法,super等價于UserMixin
self.role = kwargs['role_id']
if self.role is None:
if self.email == self.config_content.ADMINS:
#驗證email是否為設(shè)置的管理員的email
self.role = Role.query.filter_by(permissions=0xff).first()
if self.role is None:
#如果經(jīng)過了上一步權(quán)限還為空,就給個默認(rèn)的User權(quán)限
self.role = Role.query.filter_by(default=True).first()

第4行是管理員為普通員工注冊的時候提供的權(quán)限,如果是博客權(quán)限為空的用戶,即剛注冊的用戶,可以刪除第4行,若是用戶沖了一個尊貴的會員就需要單獨賦予權(quán)限了,所以我們可以在User模型里創(chuàng)建一個修改權(quán)限的方法,需要的時候調(diào)用就可以。

3,用它來對用戶進行限制: 
3.1,寫一個用來判斷用戶權(quán)限的方法,傳入用戶需要的權(quán)限,進行驗證,符合返回True,否則為False。這個方法在User模型里面:

    def can(self,permissions):
#這個方法用來傳入一個權(quán)限來核實用戶是否有這個權(quán)限,返回bool值
return self.role is not None and\
(self.role.permissions & permissions) == permissions def is_administrator(self):
#因為常用所以單獨寫成一個方法以方便調(diào)用,其它權(quán)限也可以這樣寫
return self.can(Permission.ADMINISTRATOR)

3.2 將上面方法寫入修飾函數(shù)中

#encoding:utf8

from functools import wraps
from flask import abort
from flask_login import current_user
from app.models import Permission def permission_required(permission):
def decorator(f):
@wraps(f)
def decorated_function(*args,**kwargs):
if not current_user.can(permission):
abort(403)
return f(*args, **kwargs)
return decorated_function
return decorator def admin_required(f):
return permission_required(Permission.ADMINISTRATOR)(f)

3.3 用修飾函數(shù)對有權(quán)限要求的路由進行修飾:

@main.route('/forbid',methods=['GET','POST'])
@login_required
@permission_required(Permission.FORBID)
def forbid():
return 'Hello World'

4新用戶注冊:

在view中添加如下代碼:

##注冊
@main.route('/register',methods=['GET','POST'])
@login_required
@permission_required(Permission.ASSIGN)
def register():
form = RegisterationForm()
if form.validate_on_submit():
register_judge_obj = register_judge(form.permission.data)
role_id = register_judge_obj.judge()
user = User(username=form.username.data,password=form.password.data,email=form.email.data,role_id = role_id)
db.session.add(user)
db.session.commit()
return redirect(url_for('main.login'))
return render_template('register.html',form=form)

其中調(diào)用的register_judge類代碼為

# -*- coding: utf-8 -*-
from app.models import Role class register_judge: def __init__(self,permission_id):
self.permission_id = permission_id def judge(self):
if self.permission_id == '':
role_id = Role.query.filter_by(id=4).first()
elif self.permission_id == '':
role_id = Role.query.filter_by(id=3).first()
elif self.permission_id == '':
role_id = Role.query.filter_by(id=1).first()
else:
role_id = Role.query.filter_by(default=True).first()
return role_id

實際操作過程中遇到的坑:

1,權(quán)限存入數(shù)據(jù)庫中數(shù)值改變:它其實是以2進制的方式來處理的

    0b00000001
0b00000010
0b00000100
0b10000000
如果只是第一個權(quán)限,它的值為1
如果是第二個權(quán)限(0b00000001|0b00000010)即0b00000011,即3
第三個(0b00000010|0b00000010|0b00000010)即0b00000111即7
以此類推
它并不是以10進制來計算的

2,裝飾函數(shù)的理解存在問題。

總結(jié)

以上是生活随笔為你收集整理的Flask权限管理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。