jwt 存在哪

最近一直在使用 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

image.png

之後每一個請求頭裏面都會自帶 cookie 了json

image.png

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。瀏覽器

相關文章
相關標籤/搜索