Flask博客項目-用戶權限(十五)

此前我們創建了登錄、註冊模塊,那麼自然也需要有身份的轉變,如從遊客→用戶

這裏我們使用Flask-Principal來實現用戶的權限設置

首先,安裝Flask-Principal


那相應地,我們需要一個身份表來表示身份

先添加關聯表(models.py)

roles = Table('role_users', db.Model.metadata,
              Column('u_id', Integer(), ForeignKey('user.id')),
              Column('r_id', Integer(), ForeignKey('role.id')))

給User表添加關聯(models.py)

class User(db.Model):
    ...
    roles = relationship('Role', secondary=roles, backref=backref('users', lazy='dynamic'))

添加Role表(models.py)

class Role(db.Model):
    id = Column(Integer(), primary_key=True)
    name = Column(String(80), unique=True)
    description = Column(String(255))
    
    def __init__(self, name):
        self.name = name
        
    def __repr__(self):
        return "<Role '{}'>".format(self.name)

 


接着,我們在shell中爲role表添加3個角色(管理員,文章作者,默認用戶)


 開始對Principal進行初始化:

Flask Principal提供了兩種Need對象:UserNeed和RoleNeed

每種身份會關聯到Need對象(定義了該身份能做什麼事情)

打開extensions.py:

from flask_principal import Principal, Permission, RoleNeed

principals = Principal()

admin_permission = Permission(RoleNeed('admin'))
poster_permission = Permission(RoleNeed('poster'))
default_permission = Permission(RoleNeed('default'))
...

在app中註冊:

from webapp.extensions import bcrypt, login_manager, principals
from flask_principal import identity_loaded, UserNeed, RoleNeed
from flask_login import current_user

def create_app(object_name):
    ...
    principals.init_app(app)
    
    @identity_loaded.connect_via(app)
    def on_identity_loaded(sender, identity):
        identity.user = current_user
        
        if hasattr(current_user, 'id'):
            identity.provides.add(UserNeed(current_user.id))
            
        if hasattr(current_user, 'roles'):
            for role in current_user.roles:
                identity.provides.add(RoleNeed(role.name))

其中,我們結合了flask_login的current_user來獲取當前用戶狀態(身份)

在create_app()函數中定義了on_identity_loaded()函數:來獲取用戶的權限(角色)


然後我們需要進行身份的轉變,如:遊客→文章作者,遊客→管理員:

我們打開main,py修改視圖函數:

from flask_principal import Identity, AnonymousIdentity, identity_changed
from flask import current_app

...

@main_blueprint.route('/login', methods=['GET', 'POST'])
def login():
    if form.validate_on_submit():
        ...
        if form.validate():
            login_user(user, remember=form.remember.data)
            identity_changed.send(current_app._get_current_object(), identity=Identity(user.id))
            return redirect(request.args.get('next') or url_for('main.index'))

@main_blueprint.route('/logout', methods=['GET', 'POST'])
def logout():
    from flask_login import logout_user
    logout_user()
    identity_changed.send(current_app._get_current_object(), identity=AnonymousIdentity())
    ...

那麼我們現在就可以使用角色權限了,比如只有文章作者纔可以進入文章編輯頁面:

我們打開blog.py:

from flask_login import login_required

from webapp.extensions import poster_permission

@blog_blueprint.route('/edit/<int:id>', methods=['GET', 'POST'])
@login_required
@poster_permission.require(http_exception=403)
def edit_post(id):
    ...

因爲我們希望管理員也有權限進行修改,所以可以改成 

from webapp.extensions import poster_permission, admin_permission
from flask_principal import Permission, UserNeed
from flask import abort

@blog_blueprint.route('/edit/<int:id>', methods=['GET', 'POST'])
@login_required
@poster_permission.require(http_exception=403)
def edit_post(id):
    post = Post.query.get_or_404(id)
    permission = Permission(UserNeed(post.user.id))
    
    if permission.can() or admin_permission.can():
        form = PostForm()
        
        if form.validate_on_submit():
            post.title = form.title.data
            post.text = form.text.data
            post.publish_date = datetime.datetime.now()

            db.session.add(post)
            db.session.commit()

            return redirect(url_for('blog.post', post_id=post.id))

        form.text.data = post.text

        return render_template('edit.html', form=form, post=post)

    abort(403)

點擊此處查看Git源碼


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章