
近期业务用到微信登陆并同步 mongo 数据库,但目前微信官方只给了wafer2-quickstart-nodejs这个 koa2+mysql 方案,google+git 也并没有找到轮子或方案,就自己写了个轮子(附小程序 demo ) 地址:https://github.com/seawind8888/weapp-node-mongo-scaffold
微信官方文档只给了微信登录流程图,但并没有给出同步数据库登录的流程。并且各种 openId、sessionKey、iv 等相关的鉴权字段也是搞得人很懵逼,按照自己轮流程做了个图,供参考 
先启动项目
使用微信开发者工具导入项目目录下 example 项目,并填入自己申请的AppID
进入项目,关闭详情 - 不校验合法域名 
点击微信同步登陆,提示用户入库成功,并返回 session_key 和 token (可存入 storage 并加入请求 header ) 
mongo 入库用户信息成功 
Tips: 客户端调用 wx.login 生成 token,实际有两个鉴权逻辑(微信鉴权,客户端交互 token 鉴权),客户端可先使用 wx.checkSession 判断微信鉴权,再获取客户端鉴权
loginAction = async (ctx) => { // 调用 /user/login const { encryptedData, code, iv } = ctx.query const { AppID, AppSecret } = config.weapp // 开始获取 openId && session_key const resultData = await this.getAppId({ appid: AppID, secret: AppSecret, code: code }); // 解密微信签名,获取用户信息 const decode = new WXBizDataCrypt(AppID, resultData.session_key) const userInfo = decode.decryptData(encryptedData, iv) // 引入小程序用户的 model const WeChatUser = mongoose.model('User'); // 查询用户信息 await WeChatUser.findOne({ openid: resultData.openid }) .exec() .then(async result => { // 设置 token 格式 const userToken = { openid: resultData.openid } if (!result) { // 首次登录生成 token, 有效期为 24 小时 const token = jwt.sign(userToken, secret, { expiresIn: 60 * 60 * 24 }) const NewWechatUser = new WeChatUser({ // 用户信息入库 avatar: userInfo.avatarUrl, nickName: userInfo.nickName, openid: resultData.openid, token: token }); try { const _save = await NewWechatUser.save() console.log('[mongoSave]', _save) //成功返回 code=200,并返回成 sessionKey ctx.body = { statusCode: 200, message: '登录成功, 用户信息入库成功', Token: token, sessionKey: resultData.session_key }; } catch (error) { //失败返回 code=500,并返回错误信息 console.log('[tokenSave]', error) ctx.body = { statusCode: 500, message: '参数错误', data: error } } } else { // 已添加 token const token = result.token try { // token 校验 await jwt.verify(token, secret) ctx.ody = { statusCode: 200, message: '登录成功,用户已入库', Token: token, sessionKey: resultData.session_key }; } catch (err) { if (err && err.name == 'TokenExpiredError') { // token 失效 const token = jwt.sign(userToken, secret, { expiresIn: 60 * 60 * 24 }) // 更新 token const _update = WeChatUser.updateOne(secret, token) console.log('[mongoUpdate]', _update) ctx.body = { statusCode: 200, message: '登录成功,Token 更新成功', Token: token, sessionKey: resultData.session_key }; } else { console.log('[tokenVerify]', error) ctx.body = { statusCode: 500, message: '服务器内部错误', data: error } }; } } }); }