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源码


 

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