node學習---jwt實現驗證使用者身份

Hsumo發表於2018-10-06

個人主要使用的前後端框架是 express + mongodb + mongoose + vue + elementUI, 前後端分離
本文主要記錄使用 express-jwt + jsonwebtoken 實現驗證使用者身份。

node 程式碼

node學習---jwt實現驗證使用者身份
專案的目錄結構如左圖。
    // app.js
    import expressJwt from 'express-jwt'
    import config from './config/index'
    // 自己定義簽名
    const secret = config.session.secret
    // 使用中介軟體驗證 token 合法性
    app.use(expressJwt({
      secret: secret,
      credentialsRequired: false,
      // 自定義 getToken 預設有這個函式
      getToken: function fromHeaderOrQuerystring (req) {
        let token = null
        // 此處的Bearer可以自定義,express-jwt預設採用此欄位,但需要前端請求頭保持一致
        if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
            token = req.headers.authorization.split(' ')[1]
        } else if (req.query && req.query.token) {//支援 get
            token = req.query.token.split(' ')[1]
        }
        return token
      }
    }).unless({
      path: ['/api/admin/login', '/api/admin/register']
    }))
    // 攔截器
    app.use(function (err, req, res, next) {
      //當token驗證失敗時會丟擲如下錯誤
      if (req.method !== 'OPTIONS') {
        if (err.name === 'UnauthorizedError') {
          //這個需要根據自己的業務邏輯來處理( 具體的err值 請看下面)
          res.status(401).send({
            code: 401,
            sucess: false,
            message: 'token 驗證失敗'
          })
        }
      }
    })

// admin.js
在login介面中驗證了登陸合法性後
let token = jwt.sign({adminId: admin.adminId}, secret, {
  expiresIn: 60 * 60 * 12
})
res.send({
  code: 200,
  data: {
    token: token,
    user: admin
  },
  success: true
})
secret 必須和 app.js 中設定的 secret 一致
複製程式碼
複製程式碼

前端程式碼

專案用 vue-cli 構建,引入 axios


// main.js
import axios from 'axios'
import VueAxios from 'vue-axios'

Vue.use(VueAxios, axios)
Vue.use(ElementUI)
// 通過攔截器設定請求頭
axios.interceptors.request.use(config => {
  let token = localStorage.getItem('token')
  config.headers['Authorization'] = `Bearer ${token}`
  return config
}, error => {
  return Promise.reject(error)
})

// login.vue
async login () {
  try {
  // 做了response的 success 為 false 的全域性處理,所以這邊 resp 會少一層
    const resp = await this.axios.post('/api/admin/login', this.loginForm)
    localStorage.setItem('token', resp.data.token)
  } catch (e) {
    console.error(e)
  }
}
複製程式碼

其實很簡單,但是也看了很多文章,程式碼基本都是 copy 其他文章的,但是因為看到的大部分並沒有特別詳細,還是折騰了挺久,所以特此寫下這邊文章,畢竟好記性不如爛筆頭,雖然node之父都去搞go了,但是node還是要學習學習的

相關文章