Python Flask 拦截器

拦截器

对接口请求进行预先处理,然后再交由控制器。(中间关卡)

在这里插入图片描述

比如用户如果没有登录,则拦截器直接拦截请求,不会将请求转发给控制器。进而实现对接口的权限控制。

在Flask 中,拦截器主要有两种:

全局拦截器

应用于Flask实例(app)中,对所有经过当前系统的请求进行拦截检查。

需要在函数前加上@app.before_request这个装饰器,意为在处理请求前应该做的事情

import os

from flask import Flask, request, session

app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(24)  # 生成24位的随机数种子,用于产生SESSION ID


@app.route('/article/<int:article_id>')
def test(article_id):
    """
    路由地址参数, 必须同步定义在接口函数里,作为形参
    """
    return f'你正在访问编号为:{article_id}的文章'


@app.route('/sess')
def sess():
    session['is_login'] = 'true'
    return 'done'


@app.before_request
def before():
    """
    针对app实例定义全局拦截器
    """
    url = request.path  # 读取到当前接口的地址
    if url == '/sess':
        pass
    elif session.get('is_login', '') != 'true':
        return '你还没有登录'
    else:
        pass
    

if '__name__' == '__main__':
    app.run()

这个时候,无论该网站的什么地址,只要不是is_login == 'true',请求就会被事先拦截
在这里插入图片描述

想进去,必须先 '登录' ,得到这个session
在这里插入图片描述

接着之前的访问,成功了
在这里插入图片描述

可是这样的拦截器有很多缺点:

  • 需要制定白名单

    • 因为拦截器作用在全局,那么所有的网页,静态资源,js一概会被拦截,导致有些必要网页根本加载不出来

    • 有了白名单就可以保证哪些网页和资源可以正常加载,定制白名单是比较麻烦的,后期可能还会不断修改它

      拦截器函数可能要这样写

      @app.before_request
      def before():
          """
          针对app实例定义全局拦截器
          """
          url = request.path  # 读取到当前接口的地址
          pass_list = ['/', 'reg', 'login', 'sess']
          suffix = url.endswith('.png') or url.endswith('.jpg') or url.endswith('.css') or url.endswith('.js')
          if url in pass_list or suffix:
              pass
          elif session.get('is_login') != 'true':
              return '你还没有登录'
          else:
              pass
      
  • 降低了服务器的性能

    • 要对每个接口都进行拦截器预先判断

模块拦截器

也叫视图拦截器,只针对某一个模块进行拦截,应用于Blueprint模块中。

把需要事前拦截的接口和拦截器一起放在一个视图模板里

controller/auth.py

from flask import Blueprint, session

auth = Blueprint('auth', __name__)


@auth.route('/article/<int:article_id>')
def article(article_id):
    """
    路由地址参数, 必须同步定义在接口函数里,作为形参
    """
    return f'你正在访问编号为:{article_id}的文章'


@auth.before_request
def before():
    if session.get('is_login') != 'true':
        return '你还没有登录'
    else:
        pass

main.py

import os

from flask import Flask, request, session

from controller.auth import auth

app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(24)  # 生成24位的随机数种子,用于产生SESSION ID
app.register_blueprint(auth)


@app.route('/sess')
def sess():
    session['is_login'] = 'true'
    return 'done'
    

if '__name__' == '__main__':
    app.run()

在这里插入图片描述

可以看到,只有设置了拦截器的接口是访问不了的,其他的页面包括图片,css,js等都能成功加载并渲染

在这里插入图片描述

接着得先获取session,才能成功访问接口
在这里插入图片描述

在这里插入图片描述

全局拦截器在需要控制极其隐私的地方可以使用,比如网站的后台管理接口等,其他的地方不推荐使用

模块拦截器把很多不同功能的拦截器分开来,模块化。将权限分成好几个等级,不同等级可以访问不同的接口,是安全高效的

posted @ 2022-04-07 11:17  王舰  阅读(4623)  评论(0编辑  收藏  举报