個人主要使用的前後端框架是 express + mongodb + mongoose + vue + elementUI, 前後端分離
本文主要記錄使用 express-jwt + jsonwebtoken 實現驗證使用者身份。
node 程式碼
專案的目錄結構如左圖。
// 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還是要學習學習的