Flask中使用用戶角色role擴(kuò)充Flask的用戶子系統(tǒng)(用戶權(quán)限認(rèn)證系統(tǒng))

Web 程序中的用戶并非都具有同樣地位。在大多數(shù)程序中,一小部分可信用戶具有額外權(quán)

成都創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)、永昌網(wǎng)絡(luò)推廣、小程序定制開發(fā)、永昌網(wǎng)絡(luò)營銷、永昌企業(yè)策劃、永昌品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);成都創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供永昌建站搭建服務(wù),24小時(shí)服務(wù)熱線:13518219792,官方網(wǎng)址:muchs.cn

限,用于保證程序平穩(wěn)運(yùn)行。管理員就是最好的例子,但有時(shí)也需要介于管理員和普通用

戶之間的角色,例如內(nèi)容協(xié)管員。

有多種方法可用于在程序中實(shí)現(xiàn)角色。具體采用何種實(shí)現(xiàn)方法取決于所需角色的數(shù)量和細(xì)

分程度。例如:

            1)簡單的程序可能只需要兩個(gè)角色,一個(gè)表示普通用戶,一個(gè)表示管理員。

                 對于這種情況,在 User 模型中添加一個(gè) is_administrator 布爾值字段就足夠了。

           2)復(fù)雜的程序可能需要在普通用戶和管理員之間再細(xì)分出多個(gè)不同等級(jí)的角色。

                 有些程序甚至不能使用分立的角色,這時(shí)賦予用戶某些權(quán)限的組合或許更合適。

本章介紹的用戶角色實(shí)現(xiàn)方式結(jié)合了分立的角色和權(quán)限,賦予用戶分立的角色,但角色使

用權(quán)限定義。

9.1 角色在數(shù)據(jù)庫中的表示

第 5 章創(chuàng)建了一個(gè)簡單的 roles 表,用來演示一對多關(guān)系。示例 9-1 是改進(jìn)后的 Role 模型。

示例 9-1 app/models.py:角色的權(quán)限

class Role(db.Model):
     __tablename__ = 'roles'
     id = db.Column(db.Integer, primary_key=True)  # 設(shè)置為主鍵
     name = db.Column(db.String(64), unique=True)  # 設(shè)置unique唯一
     default = db.Column(db.Boolean, default=False, index=True)  # index為改字段創(chuàng)建索引,default為設(shè)置默認(rèn)值
     permissions = db.Column(db.Integer)   # 以數(shù)字表示權(quán)限等級(jí)
     users = db.relationship('User', backref='role', lazy='dynamic')  # 動(dòng)態(tài)關(guān)聯(lián)

 

 

只有一個(gè)角色的 default 字段要設(shè)為 True,其他都設(shè)為 False。用戶注冊時(shí),其角色會(huì)被

設(shè)為默認(rèn)角色。

這個(gè)模型的第二處改動(dòng)是添加了 permissions 字段,其值是一個(gè)整數(shù),表示位標(biāo)志。各操

作都對應(yīng)一個(gè)位位置,能執(zhí)行某項(xiàng)操作的角色,其位會(huì)被設(shè)為 1。

顯然,各操作所需的程序權(quán)限是不一樣的。對 Flasky 開說,各種操作如表 9-1 所示。

表9-1 程序的權(quán)限

操  作                                                 位  值                                                    說  明

關(guān)注用戶                                          0b00000001(0x01)                                 關(guān)注其他用戶

在他人的文章中發(fā)表評論                  0b00000010(0x02)                         在他人撰寫的文章中發(fā)布評論

寫文章                                             0b00000100(0x04)                                     寫原創(chuàng)文章

管理他人發(fā)表的評論                         0b00001000(0x08)                         查處他人發(fā)表的不當(dāng)評論

管理員權(quán)限                                      0b10000000(0x80)                                       管理網(wǎng)站

注意,操作的權(quán)限使用 8 位表示,現(xiàn)在只用了其中 5 位,其他 3 位可用于將來的擴(kuò)充。

 9-1 中的權(quán)限可使用示例 9-2 中的代碼表示。

示例 9-2 app/models.py:權(quán)限常量

class Permission:
    FOLLOW = 0x01
    COMMENT = 0x02
    WRITE_ARTICLES = 0x04
    MODERATE_COMMENTS = 0x08
    ADMINISTER = 0x80

表 9-2 列出了要支持的用戶角色以及定義角色使用的權(quán)限位。

表9-2 用戶角色

用戶角色         權(quán)  限          說  明

匿名 0b00000000(0x00)未登錄的用戶。在程序中只有閱讀權(quán)限

用戶 0b00000111(0x07) 具有發(fā)布文章、發(fā)表評論和關(guān)注其他用戶的權(quán)限。這是新用戶的默認(rèn)角色

協(xié)管員 0b00001111(0x0f) 增加審查不當(dāng)評論的權(quán)限

管理員0b11111111(0xff)      具有所有權(quán)限,包括修改其他用戶所屬角色的權(quán)限

譯注:有點(diǎn)亂,應(yīng)該結(jié)合程序權(quán)限表9-1和9-2理解:二進(jìn)制bit值共八位<0b后面8個(gè)零>默認(rèn)無權(quán)限用戶是8位全部0,操作分別有5種(關(guān)注,評論,撰寫,屏蔽,管理權(quán)) 從右往左,依次設(shè)置為1,管理權(quán)使第八位。表9-2則是合并權(quán)限組合定義了角色,無權(quán)用戶8位全是零,普通用戶擁有撰寫,評論,關(guān)注三項(xiàng)許可權(quán)限(權(quán)限標(biāo)志位分別是1,2,3),所以二進(jìn)制許可代碼組合就是0b00000111,其他同理

示例 9-3 app/models.py::在數(shù)據(jù)庫中創(chuàng)建角色

class Role(db.Model):
 # ...
 @staticmethod
 def insert_roles():
     roles = {
     'User': (Permission.FOLLOW |
             Permission.COMMENT |
             Permission.WRITE_ARTICLES, True),
     'Moderator': (Permission.FOLLOW |
                 Permission.COMMENT |
                 Permission.WRITE_ARTICLES |
                 Permission.MODERATE_COMMENTS, False),
     'Administrator': (0xff, False)
     }
     for r in roles:
         role = Role.query.filter_by(name=r).first()
         if role is None:
         role = Role(name=r)
         role.permissions = roles[r][0]
         role.default = roles[r][1]
         db.session.add(role)
     db.session.commit()

insert_roles() 函數(shù)并不直接創(chuàng)建新角色對象,而是通過角色名查找現(xiàn)有的角色,然后再

進(jìn)行更新。只有當(dāng)數(shù)據(jù)庫中沒有某個(gè)角色名時(shí)才會(huì)創(chuàng)建新角色對象。如此一來,如果以后

更新了角色列表,就可以執(zhí)行更新操作了。要想添加新角色,或者修改角色的權(quán)限,修改

roles 數(shù)組,再運(yùn)行函數(shù)即可。注意,“匿名”角色不需要在數(shù)據(jù)庫中表示出來,這個(gè)角色

的作用就是為了表示不在數(shù)據(jù)庫中的用戶。

若想把角色寫入數(shù)據(jù)庫,可使用 shell 會(huì)話:

(venv) $ python manage.py shell
>>> Role.insert_roles()
>>> Role.query.all()
[<Role u'Administrator'>, <Role u'User'>, <Role u'Moderator'>]

9.2 賦予角色

用戶在程序中注冊賬戶時(shí),會(huì)被賦予適當(dāng)?shù)慕巧?。大多?shù)用戶在注冊時(shí)賦予的角色都是

“用戶”,因?yàn)檫@是默認(rèn)角色。唯一的例外是管理員,管理員在最開始就應(yīng)該賦予“管理

員”角色。管理員由保存在設(shè)置變量 FLASKY_ADMIN中的電子郵件地址識(shí)別,只要這個(gè)電子

郵件地址出現(xiàn)在注冊請求中,就會(huì)被賦予正確的角色。示例 9-4 展示了如何在 User 模型的

構(gòu)造函數(shù)中完成這一操作。

示例 9-4 app/models.py:定義默認(rèn)的用戶角色

class User(UserMixin, db.Model):
     # ... # 用戶字段
     def __init__(self, **kwargs):
        super(User, self).__init__(**kwargs)
         if self.role is None:
             if self.email == current_app.config['FLASKY_ADMIN']:
                 self.role = Role.query.filter_by(permissions=0xff).first()
             if self.role is None:
                 self.role = Role.query.filter_by(default=True).first()
     # ... # 用戶的其他方法

User 類的構(gòu)造函數(shù)首先調(diào)用基類的構(gòu)造函數(shù),如果創(chuàng)建基類對象后還沒定義角色,則根據(jù)

電子郵件地址決定將其設(shè)為管理員還是默認(rèn)角色

9.3 角色驗(yàn)證


為了簡化角色和權(quán)限的實(shí)現(xiàn)過程,我們可在 User 模型中添加一個(gè)輔助方法,檢查是否有指

定的權(quán)限,如示例 9-5 所示。

示例 9-5 app/models.py:檢查用戶是否有指定的權(quán)限

from flask.ext.login import UserMixin, AnonymousUserMixin
class User(UserMixin, db.Model):
 # ...
 
 def can(self, permissions):
     return self.role is not None and (self.role.permissions & permissions) == permissions
     
 def is_administrator(self):
     return self.can(Permission.ADMINISTER)

# 匿名用戶類     
class AnonymousUser(AnonymousUserMixin):

 def can(self, permissions):
     return False
     
 def is_administrator(self):
     return False
login_manager.anonymous_user = AnonymousUser

User 模型中添加的 can() 方法在請求和賦予角色這兩種權(quán)限之間進(jìn)行位與操作。如果角色

中包含請求的所有權(quán)限位,則返回 True,表示允許用戶執(zhí)行此項(xiàng)操作。檢查管理員權(quán)限的

功能經(jīng)常用到,因此使用單獨(dú)的方法 is_administrator() 實(shí)現(xiàn)。

出于一致性考慮,我們還定義了 AnonymousUser 類,并實(shí)現(xiàn)了 can() 方法和 is_administrator()

方法。這個(gè)對象繼承自 Flask-Login 中的 AnonymousUserMixin 類,并將其設(shè)為用戶未登錄時(shí)

current_user 的值。這樣程序不用先檢查用戶是否登錄,就能自由調(diào)用 current_user.can() 和

current_user.is_administrator()

如果你想讓視圖函數(shù)只對具有特定權(quán)限的用戶開放,可以使用自定義的修飾器。示例 9-6

實(shí)現(xiàn)了兩個(gè)修飾器,一個(gè)用來檢查常規(guī)權(quán)限,一個(gè)專門用來檢查管理員權(quán)限。

示例 9-6 app/decorators.py:檢查用戶權(quán)限的自定義修飾器

from functools import wraps

from flask import abort

from flask.ext.login import current_user

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.ADMINISTER)(f)

這兩個(gè)修飾器都使用了 Python 標(biāo)準(zhǔn)庫中的 functools 包,如果用戶不具有指定權(quán)限,則返

回 403 錯(cuò)誤碼,即 HTTP“禁止”錯(cuò)誤。我們在第 3 章為 404 和 500 錯(cuò)誤編寫了自定義的

錯(cuò)誤頁面,所以現(xiàn)在也要添加一個(gè) 403 錯(cuò)誤頁面。

下面我們舉兩個(gè)例子演示如何使用這些修飾器。

from decorators import admin_required, permission_required
from .models import Permission

@main.route('/admin')
@login_required
@admin_required
def for_admins_only():
     return "For administrators!"
 
@main.route('/moderator')
@login_required
@permission_required(Permission.MODERATE_COMMENTS)
def for_moderators_only():
     return "For comment moderators!"

在模板中可能也需要檢查權(quán)限,所以 Permission 類為所有位定義了常量以便于獲取。為了

避免每次調(diào)用 render_template() 時(shí)都多添加一個(gè)模板參數(shù),可以使用上下文處理器。上

下文處理器能讓變量在所有模板中全局可訪問。修改方法如示例 9-7 所示。

示例 9-7 app/main/__init__.py:把 Permission 類加入模板上下文

@main.app_context_processor
def inject_permissions():
  return dict(Permission=Permission)

網(wǎng)站題目:Flask中使用用戶角色role擴(kuò)充Flask的用戶子系統(tǒng)(用戶權(quán)限認(rèn)證系統(tǒng))
轉(zhuǎn)載來源:http://muchs.cn/article46/pisgeg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、企業(yè)建站、外貿(mào)網(wǎng)站建設(shè)、虛擬主機(jī)、網(wǎng)站內(nèi)鏈、自適應(yīng)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名