CSRF(Corss-site request forgery)即跨站请求伪造攻击,也常缩写为XSRF,是一种常见的web攻击方式。前端
简单来讲,CSRF攻击就是:用户访问正常网站A的时候,会在浏览器中留下一些登陆信息(好比cookie),恶意网站B利用这些登陆信息,伪造一些请求信息,告诉正常网站A我使合法用户,从而对网站A进行攻击。ios
下面经过一张图来阐述该攻击的过程和原理:web
在项目中防护CSRF攻击的时候,能够遵循如下几个方面:shell
下面咱们已Node + React项目为例,来阐述如何经过校验token来方式CSRF攻击。这里咱们使用到一个很成熟的第三方包:csurfnpm
须要说明的是,这个示例中后端使用cookie来辅助管理token信息,因此项目中已经使用了 cookie-parser ,更详细的信息能够参考 csurf 官当文档 。axios
从开发角度来讲,能够分为三个步骤:后端
首先执行一下脚本,讲csurf包安装到项目中:浏览器
npm install csurf
复制代码
而后在项目中引入该包,写一个生成token的API,代码示例以下:安全
var csrf = require('csurf')
var csrfProtection = csrf({ cookie: true });
app.get(`/getCsrfToken`, csrfProtection, (req, res) => {
res.send({ csrfToken: req.csrfToken() });
})
复制代码
在使用React开发的前端项目中,能够在根组件挂载完成以后,在其余全部请求以前,调用 /getCsrfToken
请求,获取token。这里建议在根组件的 componentDidMount
生命周期中发起请求,而后将获得的token保存到sessionStorage中。示例代码以下:markdown
import axios from 'axios';
componentDidMount() {
axios.get('/getCsrfToken')
.then(res => {
if (res && res.data && res.data.csrfToken) {
window.sessionStorage.setItem('CSRF-Token', res.data.csrfToken);
} else {
throw new Error("Get CSRF token failed");
}
}).catch(() => {
throw new Error("Get CSRF token failed");
});
}
复制代码
获取token以后,在其余的API请求中,都将该token设置到请求头中,一块儿发送到后端API中。这里以 axios 为例,展现如何设置请求头:
import axios from 'axios';
// 在建立axios实例的时候,设置请求头信息
this.axios = axios.create({
headers: {
'CSRF-Token': window.sessionStorage.getItem('CSRF-Token') || ""
}
})
// 修改已建立的axios实例的请求头信息
this.axios.defaults.headers.common['CSRF-Token'] = window.sessionStorage.getItem('CSRF-Token');
复制代码
如此一来,前端在发送请求的时候,就会将token信息附在请求头中,一块儿发给后端进行处理。
在前面生成token信息的时候,咱们已经经过如下代码建立了一个csurf实例:
var csrfProtection = csrf({ cookie: true });
复制代码
咱们能够直接以中间件的形式使用该实例对token进行校验,即:
app.use(csrfProtection);
复制代码
到这里,一个基本的防护CSRF攻击的措施就完成了,须要注意的是,使用csurf包进行防护CSRF攻击的时候,会校验两个变量:一个是自动添加到cookie中的_csrf,一个就是上述生成的token,两者缺一不可。
博客中若有错误之处,还但愿各位达大佬予以纠正。