在前后端分离部署的时候,我们经常会遇到一些问题,例如在执行post请求的时候,后端服务器返回:
这个时候提示:CSRF vertification failed。CSRF验证未通过。那么这个时候会有多种方法来解决。
就拿我们常用的django后端来举例,我们在使用django框架编写接口的时候,在项目目录下的setting.py中有一行:
MIDDLEWARE = [
'django.middleware.csrf.CsrfViewMiddleware'
]
其中有一个中间件名为:csrf.CsrdViewMiddleware,如果我们将这个中间件注释掉,即取消了django框架要求的csrf验证功能,这样使用的时候就不会触发csrf验证了
有时候csrf验证又是我们必须使用的,那么这个时候我们可以换一下思路,即在验证前我们去获取一下csrftoken不就好了么。
我们看一下django的关于csrf的文档,其中有这样一段话:
我们再执行Ajax request的时候可以将token信息加在请求的header中,设置的头部键为”X-CSRFToken”,这样就能保护我们使用CSRF token。
那么我们在前端post请求前在header中配置”X-CSRFToken”不就好了,有那么多次的post请求,难道要去一个个请求之前加获取CSRF token吗?那样就太麻烦了。
这时候想起axios有一个”interceptors”拦截器的功能,即在我们的请求之前拦截一次进行处理,那么我们可以像下面一样处理(我们使用的是vue-cli3):
在main.js中引入axios
import axios from 'axios'
添加拦截器
tips:
- 一定要记得在interceptors中return config,这样才能执行接下来的请求,否则会终止
- axios.get(‘/getcsrftoken’)前一定要加return,你要记得axios是一个Promise方法,在内部return的话,外部根本没有接收到,从而会导致请求终止。(在这里坑了好一会,后来一拍脑袋,少了个return)
axios.interceptors.request.use((config) => {
if (config.method === 'post') {
// 如果是post请求, 首先请求一次接口, 获得csrf_token
return axios.get('/getcsrftoken').then((response) => {
let csrfToken = response.data.data.csrf_token
config.headers['X-CSRFToken'] = csrfToken
return config
})
} else {
return config
}
}, (error) => {
// Do something with request error
return Promise.reject(error)
})
- 这个时候我们打开我们的页面,执行一次post操作,我们可以看到:
我们可以看到第一次执行了getcsrftoken的请求,之后再执行publishlist请求。我们看看publishlist请求的header值:
这是在写前端vue+后端django项目的时候遇到的一个csrf的问题,之前在网上搜索了下,然后很多都是千篇一律的答案,很多都是直接文档复制下来的,对于新手来说,不好理解与解决。在这里记录遇到的问题和解决方案,希望能够帮到大家。