最近一直在使用 jwt(JSON Web Token),前端經過用戶名、密碼登錄成功後,接口返回一個 jwt前端
// login exports.user_login = async function (req, res, next) { const { username, password } = req.body let ret = await userModel.userLogin(username, password) if (!ret) return next(createError(500)) // sql 執行失敗,直接給 500 if (ret.length !== 1) { // 用戶名或密碼錯誤 res.json({ code: 100, message: '用戶名或密碼錯誤', data: null }) } else { const user = ret[0] const token = generateJWT(user) res.json({ code: 100, message: '返回成功', data: { token } }) } } // 生成 jwt function generateJWT(user) { let now = new Date() let expire = new Date(now).getTime() + 30 * 60 * 1000 // 30 min 後過時 return jwt.sign({ id: user.id, username: user.username, password: user.password, role: user.role, exp: expire / 1000 }, SECRET) }
前端請求成功後,收到 token,存儲在本地vue
// vuex store 中 login({ commit }, userInfo) { const { username, password } = userInfo return new Promise((resolve, reject) => { login({ username: username.trim(), password }).then(res => { if (res) { commit('SET_TOKEN', res.token) setSessionItem('token', res.token) // 存到 sessionStorage 中 resolve(true) } else { resolve(false) } }).catch(error => { console.log('error: ', error) // for debug reject(error) }) }) }
而後之後每次請求接口都帶上這個 jwtios
// 請求攔截器 axios.interceptors.request.use( config => { const token = getSessionItem('token') || '' if (token) config.headers['token'] = token return config }, error => { // 對請求錯誤作些什麼 console.log(error) // for debug return Promise.reject(error) } )
以前作移動端是這麼搞的,但今天在作 PC 端一個管理後臺時,發現 jwt 存到 sessionStorage 中有個問題,同源下,不一樣的窗口 sessionStorage 中的數據不能共享,就是說打開一個窗口已經登陸了,在瀏覽器中在開一個窗口還得從新登陸,這就不能忍了sql
因而,就想成功後,將 jwt 存到 cookie 中,這樣不一樣的窗口就能夠共享了,這個存儲後端和前端均可以作,後端存儲:vuex
// login exports.user_login = async function (req, res, next) { ... const user = ret[0] const token = generateJWT(user) // express 要引入 cookie-parse res.cookie("token", token, { maxAge: 30 * 60 * 1000, httpOnly: true }) // httpOnly 爲 true,js 腳本就不能訪問了 res.json({ code: 100, message: '登陸成功' }) }
返回頭就會有 set-cookie 這個字段了express
之後每一個請求頭裏面都會自帶 cookie 了json
express 接收:req.cookies.tokenaxios
本着先後端徹底分離的原則,我採用前端來存 cookie,後端將生成的 token 仍是給到前端,前端引 js-cookie 這個庫來操做後端
// vuex store 中 login({ commit }, userInfo) { ... if (res) { commit('SET_TOKEN', res.token) setToken(res.token) resolve(true) } else { resolve(false) } ... }
用 js-cookie 這個庫設置 cookie,沒有找到怎麼設置 HttpOnly。瀏覽器