安装所需要的包

安装 request

用来发送请求,调用微信官方接口,你也可以使用axios

yarn add request

安装 dotenv

用来配置环境变量,这里用来存储加密用的SECRET

yarn add dotenv

安装完成后,在项目根目录建一个.env文件,里面加上

SECRET=随便写一段字符串

例如:
SECRET=clwy.cn

在根目录 app.js中引用

require('dotenv').config()

安装 jsonwebtoken

用来生成用户token

yarn add jsonwebtoken

开发流程

  • 微信开发者打开小程序,找到app.jswx.login方法,输出 console.log(res.code)
  • 小程序将code传递过来,实现认证流程,最后返回前端用户登录的token
  • 可以使用Postman之类的工具进行调试

Express 实现登录

  • 通过微信小程序发过来的code,调用微信官方接口获取到openid
  • 通过openid查询数据库,是否有当前用户,如果没有的话就注册一个
  • 使用jwt加密,生成token并返回
const request = require('request');
const jwt = require('jsonwebtoken');

router.post('/auth', function (req, res, next) {
    // 取得微信小程序发过来的 code
    const code = req.body.code

    // 调用微信官方登录接口
    request.get({
        uri: 'https://api.weixin.qq.com/sns/jscode2session',
        json: true,
        qs: {
            grant_type: 'authorization_code',
            appid: '你小程序的appid',
            secret: '你小程序的secret',
            js_code: code
        }
    }, async (err, response, data) => {
        // 如果微信官方返回有错误码
        if (data.errcode) {
            return res.json({success: false, msg: 'code已过期'})
        }

        //用微信官方返回的用户openid去查询本地的数据库,看有没有这个用户
        // 如果有这个用户,那就查出来
        let user = await models.User.findOne({where: {openid: data.openid}})

        // 如果没有这个用户,那就新增一个用户
        if (!user) {
            user = await models.User.create({openid: data.openid, admin: false})
        }

        // 给当前用户,生成token
        const token = jwt.sign({
            user: {
                id: user.id,
                openid: data.openid,
            },
        }, process.env.SECRET, {expiresIn: 60 * 60 * 24 * 7});

        res.json(token)
    })
})

module.exports = router;

小程序端发送 code

wx.login({
    success: res => {
        // console.log(res)
        wx.request({
            url: `http://localhost:3000/users/auth`,
            method: 'POST',
            data: {
                code: res.code
            },
            success: res => {
                // 将返回的token存储起来,调用其他需要认证接口的时候,可以直接使用
                wx.setStorageSync('token', res.data.token)
            }
        })
    }
})

小程序中使用返回的 token

let token = wx.getStorageSync('token')
wx.request({
      url: 'http://localhost:3000/orders',
      header: {
        'Accept': "*/*", //解决真机调试406
        'token': token
      },
      method: "POST",
      success: (res) => {

      }
})

需登录的接口添加验证中间件

在 Express 项目的middlewares目录中,添加checkAuth.js中间件

var jwt = require('jsonwebtoken');

module.exports = function (options) {
  return function (req, res, next) {
    // 如果没有提供 token,直接提示错误
    var token = req.headers.token;
    if (!token) {
      return res.status(401).send({
        success: false,
        message: '当前接口需要认证才能访问'
      });
    }

    // 验证token是否正确
    jwt.verify(token, process.env.SECRET, function (err, decoded) {
      if (err) {
        if (err.name == "TokenExpiredError") {
          return res.status(401).send({
            success: false,
            message: 'token已经过期,请重新登录!'
          });
        }

        if (err.name == "JsonWebTokenError") {
          return res.status(401).send({
            success: false,
            message: 'token 错误,请重新登录!'
          });
        }
      }

      // decoded里面装的是解密出来的是,之前加密生成token的东西
      // 解析出来的数据存入req
      req.decoded = decoded;
      next();
    })
  }
}

使用路由中间件

在根目录app.js

var checkAuth = require('./middlewares/checkAuth')

// 需要认证的接口加上认证中间件
app.use('/carts', checkAuth(), cartsRouter);

Express 获取当前登录用户信息

console.log(req.decoded.user)

已添加到喜欢了