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,兩者缺一不可。
博客中若有錯誤之處,還但願各位達大佬予以糾正。