# Flask拦截器



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

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

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

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

```go
@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的后缀，把一些资源文件加入白名单。

```python
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等都能成功加载并渲染。

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