flask项目下加入用户权限来控制不同用户具有不同访问权限

flask项目下加入用户权限来控制不同用户具有不同访问权限

1.首先需要在前端main.vue文件中加入拦截器,目的是每次访问的时候都把token带着:

// 设置一个拦截器,作用:每次请求时,将token加到那个包上,这样就可以将token发送到服务端

axios.interceptors.request.use(

  // 这个config表示页面向服务器发送的数据,拦截下来

  config => {

    const tokenstr = window.sessionStorage.getItem('token')

    if (tokenstr) {

      // 为拦截下来的包加入token

      config.headers.token = tokenstr

    }

    // 最后将加入token的包从新发出去

    return config

  }

)

// 设置一个相应拦截器

// 作用:当服务端返回时,有token失效或错误的状态码时,就改一下他的path让他跳转到登录页面

axios.interceptors.response.use(

  response => {

    // console.log(response)

    if (response.data.status === 10016 || response.data.status === 10017) {

      // 这个路由就是服务器返回的,然后把他里面的路径换一下

      router.replace(

        {

          path: '/login'

        }

      )

    }

    return response

  }

)

2.建议在路由文件(router.vue的最下面)中把守卫钩子函数加上:

router.beforeEach((to, from, next) => {

  if (to.path === '/login') return next()

  const tokenstr = window.sessionStorage.getItem('token')

  if (!tokenstr) return next('/login')

  // 用户不去登录页,并且已登录过,放行

  next()

})

3.可以选择加入token验证,在一个文件下,例如utils文件夹下,创建一个文件token.py

'''

    专门设置tokens的文件

    需要用到:

        加密的数据:uid

        算法:python模块

        密钥:flask_app  SECRET_KEY

       

    原理:

        避免像session那种将用户数据存储到服务器上。

        根据用户登陆过就会通过数据和密钥用加密算法生成一个tokens,然后再发送给客户端

        以后客户登录就带着这个tokens,

'''

# 得到app config中的盐

from flask import current_app,request,g

# 导入加密算法

from itsdangerous import URLSafeTimedSerializer as Serializer



from flask_student.models import User

from flask_student.utils.message import to_dict_msg

from flask_student import models

from functools import wraps



# 导入元装饰器

import functools


# 加密函数(加密内容,加密时间)

def generate_auth_token(uid,expiration):

    # 创建加密对象(密钥)

    s = Serializer(current_app.config['SECRET_KEY'])

    #生成tokens(加密的内容,加密时间)

    return s.dumps({'id':uid,'exp':expiration})




# 解密函数

def verify_auth_token(token_str):

    # 创建解密对象(密钥)

    s = Serializer(current_app.config['SECRET_KEY'])

    # 防止那个token不存在或黑客恶意攻击

    try:

        # 解密tokens对象,变成字典

        data = s.loads(token_str)

    except Exception:

        return to_dict_msg(10017)

    usr = User.query.filter_by(id = data.get("id")).first()

    return usr





# tokens装饰器函数(用户登录装饰器)

def login_required(view_func):

    @wraps(view_func)  # 这里需要 @ 符号

    def verify_token(*args, **kwargs):

        # 更安全地获取 token

        token = request.headers.get("token")

        if not token:

            return to_dict_msg(10016, msg='缺少token')

       

        # 创建解密对象

        s = Serializer(current_app.config['SECRET_KEY'])

       

        try:

            # 解密 token

            data = s.loads(token)

        except Exception:

            return to_dict_msg(10017, msg='token无效或已过期')

       

        # 验证用户是否存在

        user_id = data.get('id')

        if not user_id:

            return to_dict_msg(10018, msg='token格式错误')

       

        user = models.User.query.get(user_id)

        if not user:

            return to_dict_msg(10003, msg='用户不存在')

       

        # 设置 g 对象供后续使用

        g.user = user

        g.user_id = user_id

        g.token_data = data

       

        return view_func(*args, **kwargs)

    return verify_token

       

4.还在utils文件夹下创建文件  userPermission.py

from flask_student import models

from flask_student.utils.tokens import login_required

from flask_student.utils.message import to_dict_msg

from functools import wraps

from flask import g



'''

这是不同用户有不同权限

'''





# 用户权限加的两个普通的方法



def get_user_permissions(user_id):

    """获取用户所有权限"""

    user = models.User.query.get(user_id)

    if not user or not user.role:

        return []

   

    permissions = []

    role = user.role

   

    # 遍历角色拥有的所有菜单权限(路径就是权限,否者其他的是)

    for menu in role.menu:

        if menu.path:  # 只有有路径的菜单才算是权限

            permissions.append(menu.path)

   

    return permissions



def get_user_menu(user_id):

    """获取用户菜单树"""

    user = models.User.query.get(user_id)

    if not user or not user.role:

        return []

   

    return user.role.to_menu_list()




def permission_required(permissions=None):

    """权限验证装饰器"""

    def decorator(f):

        @wraps(f)

        @login_required

        def decorated_function(*args, **kwargs):

            # 如果不需要权限。就执行路由函数

            if not permissions:

                return f(*args, **kwargs)

           

            # 当前的用户

            user_id = g.user_id

            # user_id = session.get('user_id')

            if not user_id:

                return to_dict_msg(10002, msg='请先登录')

            # 获取当前用户的权限

            user_permissions = get_user_permissions(user_id)

           

            # 需要的权限

            required_perms = set(permissions)

            # 用户的权限

            # set的作用  1.去重,2.能用集合运算issubset()

            user_perm_set = set(user_permissions)

           

            # 判断用户权限是否是所需权限的子集

            if not required_perms.issubset(user_perm_set):

                return to_dict_msg(10005, msg='权限不足')

           

            return f(*args, **kwargs)

        return decorated_function

    return decorator

3.上面两个准备好,不要忘了,在login路由中,但是如果有token验证,这前两行代码就可以不加了。

# 这是用户权限所需要的代码

            session['user_id'] = usr.id

            session['user_name'] = usr.username

            permissions = get_user_permissions(usr.id)

            menus = get_user_menu(usr.id)

5.然后就可以在需要加验证的路由下面就可以加上验证装饰器了

例如这样:(一定要加在下面,否则不会生效)

@student.route('/student_list')

@permission_required(['/role_list'])

6.最后补充:

其实只有3,4,5才是权限设置的问题,前两个只是为了保证项目的完整性,使我们设置的能运行出来,如果是仅仅用postman测验的话,1,2是不需要的

       

转载请说明出处内容投诉
CSS教程网 » flask项目下加入用户权限来控制不同用户具有不同访问权限

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买