综合案例:使用Express开发接口服务(续)

Posted So istes immer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了综合案例:使用Express开发接口服务(续)相关的知识,希望对你有一定的参考价值。

目录

⑦用户登录开发

1.获取请求体数据
2.数据验证

3.生成token
4.发送成功响应(包含token的用户信息)

基于JWT的身份验证 https://blog.csdn.net/YINZHE__/article/details/120080256

config/config.default.js中的jwtSecret可以用UUID保证唯一性 http://www.uuid.online/ 

默认生成的token是永久有效的,但是可以自己设置有效期时间,见controller/user.js

config/config.default.js

/**
 * 默认配置
 */

module.exports = {
  dbUrl: 'mongodb://localhost:27017/realworld',
  jwtSecret: '3301a30b-7355-4398-bc02-331eb32c9f64'
}

util/jwt.js

const jwt = require('jsonwebtoken')
const { promisify } = require('util')

exports.sign = promisify(jwt.sign)

exports.verify = promisify(jwt.verify)

exports.decode = promisify(jwt.decode)

 controller/user.js

const { User } = require('../model')
const jwt = require('../util/jwt')
const { jwtSecret } = require('../config/config.default')

// 用户登录
exports.login = async (req, res, next) => {
  try {
    // 1.数据验证
    // 2.生成token
    const user = req.user.toJSON()
    console.log(user)
    const token = await jwt.sign({
      userId: user._id
    }, jwtSecret,{
      expiresIn: 60 * 60 * 24
    })
    // 3.发送成功响应(包含token的用户信息)
    delete user.password
    res.status(200).json({
      ...user,
      token
    })
  } catch(err) {
    next(err)
  }
}

...    //其它代码不变

validator/user.js

const validate = require('../middleware/validate')
const { body } = require('express-validator')
const { User } = require('../model')
const md5 = require('../util/md5')

... //原代码不变

exports.login = [
  validate([
    body('user.email').notEmpty().withMessage('邮箱不能为空'),
    body('user.password').notEmpty().withMessage('密码不能为空')
  ]),
  validate([
    body('user.email').custom(async (email, { req }) => {
      const user = await User.findOne({ email })
        .select(['email','username','bio','image','password'])
      if (!user) {
        return Promise.reject('用户不存在')
      }
      // 将数据挂载到请求对象中,后续的中间件也可以使用了
      req.user = user
    })
  ]),
  validate([
    body('user.password').custom(async (password, { req }) => {
      if(md5(password) !== req.user.password) {
        return Promise.reject('密码错误')
      }
    })
  ])
]

router/user.js

const express = require('express')
const userCtrl = require('../controller/user')
const userValidator = require('../validator/user')

const router = express.Router()

// 用户登录
router.post('/users/login', userValidator.login, userCtrl.login)

...    //原代码不变

module.exports = router

生成token并发送

⑧获取用户信息 

在获取之前,首先要验证token

router/user.js 

const express = require('express')
const userCtrl = require('../controller/user')
const userValidator = require('../validator/user')
const auth = require('../middleware/auth')

const router = express.Router()

...    //原代码不变

// 获取当前登录用户
router.get('/user', auth, userCtrl.getCurrentUser)

...    //原代码不变

module.exports = router

controller/user.js

const { User } = require('../model')
const jwt = require('../util/jwt')
const { jwtSecret } = require('../config/config.default')

...    //原代码不变

// 获取当前登录用户
exports.getCurrentUser = async (req, res, next) => {
  try {
    res.status(200).json({
      user: req.user
    })
  } catch(err) {
    next(err)
  }
}

...    //原代码不变

 middleware/auth.js

const { verify } = require('../util/jwt')
const { jwtSecret } = require('../config/config.default')
const { User } = require('../model')

module.exports = async (req,res,next) => {
  // 从请求头获取token数据
  let token = req.headers['authorization']
  token = token ? token.split('Bearer ')[1] : null
  if(!token) {
    return res.status(401).end()
  }
  try {
    const decodedToken = await verify(token, jwtSecret)
    req.user = await User.findById(decodedToken.userId)
    next()
  } catch(err) {
    return res.status(401).end()
  }
}

效果

这里的token是之前登录生成的token

 在postman中,也可以统一设置请求头中的Authorization,这样就不用每次添加了

以上是关于综合案例:使用Express开发接口服务(续)的主要内容,如果未能解决你的问题,请参考以下文章

综合案例:使用Express开发接口服务

Express接口综合案例(创建项目配置常用中间件路由设计提取控制器模块配置错误统一处理中间件用户注册的数据验证,密码加密)

java基础---25. 接口多态综合案例

实践案例丨Netty案例集锦之多线程篇(续)

接口测试-综合技能篇之案例一

Express接口案例 使用jsonwebtoken