个人主要使用的前后端框架是 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还是要学习学习的