本篇僅適合使用Nuxt+express的使用者。
首先先設置後端,在express官網推薦使用套件csurf,依照套件文件指示,如果要使用cookie認證,還要安裝cookie-parser。
npm install cookie-parser csurf
因為要配合Nuxt後端的銜接程式,所以比較難在單一某個route設置csrf保護,所以就一律設成全域使用,這樣做所有的Post和Put的Route都會檢查csrf token。
var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var express = require('express')
var app = express()
app.use(cookieParser())
app.use(csrf({ cookie: true }))
再來要將每次的網頁請求,要返回的csrf token送給Nuxt,在Nuxt的文件中,只有一個地方可以跟後端的express做銜接,就是在store/index.js,可參考官網網址,這個蠻特別的,包括要從express傳session資料到Nuxt都要用這個。
export const state = () => ({
csrf_token: ''
})
export const mutations = {
set_csrf_token (state, val) {
state.csrf_token = val
}
}
export const actions = {
// nuxtServerInit is called by Nuxt.js before server-rendering every page
nuxtServerInit ({ commit }, { req }) {
//set csrf
commit('set_csrf_token', req.csrfToken())
}
}
這樣做就能保證每次要求網頁,都能將伺服端產生的csrf token保存在Nuxt的store裡面了。
接著我們要設定Nuxt的axios模組,讓它每次在傳送資料到後端的時候,能自帶header參數。因為根據剛csruf的設定,每次的post都會檢查header是否有 ‘CSRF-Token’ 的參數,並檢查token是否正確。
首先先設定nuxt.config.js
plugins: [
'~/plugins/axios'
],
在plugins資料夾新增一個axios.js的檔案,內容如下
export default function ({ $axios, app, store }) {
$axios.onRequest(config => {
config.headers.common['CSRF-Token'] = store.state.csrf_token
})
}
如此一來每次在做post的時候,應該就能自帶一個’CSRF-Token’的參數在header裡面了。測試看看吧。
let res = await this.$axios.$post('/test/csrf/', { name: 'John' })
console.log(res)
大功告成。