Flask拦截器

一、全局拦截器 一般是在所有路由前添加一个@app.before_request 判断语句和以前一样,如果没有登录提示未登录,如果登录了就pass

@app.before_request
def before():
    _id = session.get("_id", None)
    if not _id:
        return result(203, {"info": "未登录"})
    else:
        pass

但这样也有一个问题,有些路由函数,例如登录和注册不能被拦截。试想一个用户连账号都没有,或者还没有登录就检索他的id,结果必然是未登录甚至报错。并且因为拦截器作用在全局,那么所有的网页,静态资源,js一概会被拦截,导致有些必要网页根本加载不出来。

这时候就要设置白名单,来过滤掉一些内容

@app.before_request
def before():
    url = request.path  # 当前请求的URL
    passUrl = ["/login", "/regist"]
    if url in passUrl:
        pass
    else:
        _id = session.get("_id", None)
        if not _id:
            return result(203, {"info": "未登录"})
        else:
            pass

通过passUrl = ["/login", “/regist”]设置了白名单,如果当前url在白名单内则不会拦截。

还可以通过筛选url的后缀,把一些资源文件加入白名单。

suffix = url.endswith('.png') or url.endswith('.jpg') or url.endswith('.css') or url.endswith('.js')
if url in passUrl or suffix:
    pass

总结来讲,全局拦截器的确避免了重复,但也有一些缺点:

  • 需要制定白名单

  • 对每个接口都进行拦截判断,降低了服务器的性能

二、模块拦截器

也叫视图拦截器,只针对某一个模块进行拦截,应用于Blueprint模块中。 把需要事前拦截的接口和拦截器一起放在一个视图模板里。

代码与全局拦截器一样,但位置放在了某一模块的py文件里。这样一来,只有设置了拦截器的接口是访问不了的,其他的页面包括图片,css,js等都能成功加载并渲染。

@app.before_request
def before():
    print('ok')

Last updated