node学习---jwt实现验证用户身份

360 阅读2分钟

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