Giter Site home page Giter Site logo

wafer2-node-sdk's Introduction

Wafer 服务端 SDK - Node.js

介绍

Wafer 服务端 SDK 是腾讯云为微信小程序开发者提供的快速开发库,SDK 封装了以下功能供小程序开发者快速调用:

  • 用户登录与验证
  • 信道服务
  • 图片上传
  • 数据库
  • 客服消息

开发者只需要根据文档对 SDK 进行初始化配置,就可以获得以上能力。你还可以直接到腾讯云小程序控制台购买小程序解决方案,可以得到运行本示例所需的资源和服务,其中包括已部署好的相关程序、示例代码及自动下发的 SDK 配置文件 /etc/qcloud/sdk.config

安装

npm install wafer-node-sdk --save

配置

const configs = {
  appId: 'wx00dd00dd00dd00dd',
  appSecret: 'abcdefghijkl',
  useQcloudLogin: false,
  cos: {
    region: 'cn-south',
    fileBucket: 'test',
    uploadFolder: ''
  },
  serverHost: '1234567.qcloud.la',
  tunnelServerUrl: '1234567.ws.qcloud.la',
  tunnelSignatureKey: 'abcdefghijkl',
  qcloudAppId: '121000000',
  qcloudSecretId: 'ABCDEFG',
  qcloudSecretKey: 'abcdefghijkl',
  wxMessageToken: 'abcdefghijkl'
}
const qcloud = require('qcloud-weapp-server-sdk')(configs)

具体配置项说明请查看:API 文档

API 文档

具体查看 API 文档

基本功能

用户登录与验证

用户登录使用 authorization 接口:

const { auth: { authorization } } = qcloud

// express
module.exports = (req, res) => {
  authorization(req).then(result => {
    // result : {
    //   loginState: 0  // 1表示登录成功,0表示登录失败
    //   userinfo: { // 用户信息.. }
    // }
  })
}

用户登录态校验使用 validation 接口:

const { auth: { validation } } = qcloud

// express
module.exports = (req, res) => {
  validation(req).then(result => {
    // result : {
    //   loginState: 0  // 1表示登录成功,0表示登录失败
    //   userinfo: { // 用户信息.. }
    // }
  })
}

如果你使用 Koa 框架,则可以直接使用 SDK 导出的 koaAuthorizationkoaValidation 中间件,登录信息将会被写进 ctx.state.$wxInfo

const { auth: { authorizationMiddleware, validationMiddleware } } = qcloud

// 颁发登录态
router.get('/login', authorizationMiddleware, ctx => {
  console.log(ctx.state.$wxInfo)
  // {
  //   loginState: 0  // 1表示登录成功,0表示登录失败
  //   userinfo: { // 用户信息.. }
  // }
})

// 校验登录态
router.get('/user', validationMiddleware, ctx => {
  console.log(ctx.state.$wxInfo)
  // {
  //   loginState: 0  // 1表示登录成功,0表示登录失败
  //   userinfo: { // 用户信息.. }
  // }
})

信道服务

业务在一个路由上(如 /tunnel)提供信道服务,只需把该路由上的请求都交给 SDK 的信道服务处理即可。使用信道服务需要实现处理器,来获取处理信道的各种事件,具体可参考配套 Demo 中的 tunnel.js 的实现。

图片上传

SDK 提供直接上传图片至腾讯云对象储存(COS)的接口,只需要将请求传入接口,即可自动上传文件到 COS 中,并返回数据:

const { uploader } = qcloud

module.exports = async ctx => {
  await uploader(ctx.req).then(data => {
    console.log(data)
    // {
    //   imgUrl: 'http://test-121000000.cosgz.myqcloud.com/abcdef.jpg',
    //   size: 1024,
    //   mimeType: 'image/jpeg',
    //   name: 'abcdef.jpg'
    // }
  })
}

数据库

SDK 还暴露出了内部使用的 MySQL 连接,由于 SDK 内部使用 Knex.js 连接数据库,SDK 暴露的 MySQL 实例就是 Knex.js 连接实例,具体使用方法可以查看 Knex.js 文档

const { mysql } = qcloud

mysql('db_name').select('*').where({ id: 1 })
// => { id:1, name: 'leo', age: 20 }

客服消息

微信提供一个客服消息处理能力,你可以使用 SDK 提供的接口快速部署一个接受客服信息的 API:

const { message: { checkSignature } } = require('../qcloud')

/**
 * 响应 GET 请求(响应微信配置时的签名检查请求)
 */
router.get('/message', ctx => {
  const { signature, timestamp, nonce, echostr } = ctx.query
  if (checkSignature(signature, timestamp, nonce)) ctx.body = echostr
  else ctx.body = 'ERR_WHEN_CHECK_SIGNATURE'
})

// post 请求用来接收消息
router.post('/message', (ctx, next) {
    // 检查签名,确认是微信发出的请求
    const { signature, timestamp, nonce } = ctx.query
    if (!checkSignature(signature, timestamp, nonce)) ctx.body = 'ERR_WHEN_CHECK_SIGNATURE'

    /**
     * 解析微信发送过来的请求体
     * 可查看微信文档:https://mp.weixin.qq.com/debug/wxadoc/dev/api/custommsg/receive.html#接收消息和事件
     */
    const body = ctx.request.body

    ctx.body = 'success'
})

示例 Demo

腾讯云还提供了完整的示例代码,点击这里下载。

wafer2-node-sdk's People

Contributors

jas0ncn avatar miwoy avatar poorenme avatar shasharoman avatar sqrtqiezi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wafer2-node-sdk's Issues

关于多URL-信道的BUG

某种场景,我希望在一个工程里面使用两个不同的信道URL做不同业务,发现有BUG。

假设:

  • 学生业务:/student/tunnel
  • 老师业务:/teacher/tunnel

然后在分别在对应的GET方法中使用tunnel.getTunnelUrl(ctx.req)返回信道的连接URL,但客户端连接后通信会出现消息错乱,比如发给学生的消息出现在老师的处理逻辑中,原因是lib/tunnel/service.js中的receiveUrl方法中做了一个Cache,导致两个业务GET方法中的getTunnelUrl传给信道服务器的receiverUrl是同一个。

如果真有这种场景,可以修改lib/tunnel/service.js,删除缓存的逻辑:

function receiveUrl (pathname) {
        const protocol = url.parse(config.tunnelServerUrl).protocol
        const hostname = config.serverHost
        const port = config.serverPort // 配置端口号,undefined则无效果
        return url.format({ protocol, hostname, port, pathname })
}

解密数据发生错误

client端没有使用wafer2-client-sdk,自己组织的请求,发送到服务器端。有时会在解密数据时发生错误。
错误如下。烦请帮忙排查,谢谢。

错误信息:
ERR_IN_DECRYPT_DATA
Error: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt

报错代码行:

decryptedData = aesDecrypt(session_key, iv, encryptedData)

tunnelServerUrl 和 tunnelSignatureKey

如果没有购买小程序解决方案, 我改如何获取这两个东西呢?我单独购买的腾讯云服务器。(其实当时就是想试试小程序,当时还没有什么方案)

不支持 Express?

虽然没直接写出, 但是可以看出来使用这个SDK的前提是使用koa框架儿不是express?

新用户首次登录,在authorization方法中出现异常

wafer-node-sdk\lib\auth\index.js

原代码:

// 如果只有 code 视为仅使用 code 登录
if (code && !encryptedData && !iv) {
    return getSessionKey(code).then(pkg => {
        const { openid, session_key } = pkg
        // 生成 3rd_session
        const skey = sha1(session_key)

        return AuthDbService.getUserInfoByOpenId(openid).then(userinfo => {
             **wxUserInfo = JSON.parse(userinfo.user_info)**

            return AuthDbService.saveUserInfo(wxUserInfo, skey, session_key)
            .then(userinfo => ({
                loginState: LOGIN_STATE.SUCCESS,
                userinfo: {
                    userinfo: wxUserInfo,
                    skey: userinfo.skey
                }
            }))
        })
    })
}

这一句在新用户初次登录时,从cSessionInfo表查回的信息必然为空,导致JSON.parse抛出异常

此处建议修改为:

            const wxUserInfo = {'openId':openid}
            if (userinfo !== undefined){
                if ('user_info' in userinfo){
                    wxUserInfo = JSON.parse(userinfo.user_info)
                }
            }

此代码修改已经验证。

求助大神:本地部署,登陆时报错Cannot read property 'user_info' of undefined

【nodemon提示报错如下】
koa-weapp-demo Catch Error: TypeError: Cannot read property 'user_info' of undefined at AuthDbService.getUserInfoByOpenId.then.userinfo (/data/release/weapp/node_modules/wafer-node-sdk/lib/auth/index.js:41:56) at runCallback (timers.js:810:20) at tryOnImmediate (timers.js:768:5) at processImmediate [as _immediateCallback] (timers.js:745:5) From previous event: at Builder.Target.then (/data/release/weapp/node_modules/knex/lib/interface.js:36:24) at getSessionKey.then.pkg (/data/release/weapp/node_modules/wafer-node-sdk/lib/auth/index.js:40:62) at at process._tickCallback (internal/process/next_tick.js:188:7) +2ms

【/……/auth/index.js附近代码】

// 如果只有 code 视为仅使用 code 登录
if (code && !encryptedData && !iv) {

    return getSessionKey(code).then(pkg => {
        const { openid, session_key } = pkg
        // 生成 3rd_session
        const skey = sha1(session_key)
        return AuthDbService.getUserInfoByOpenId(openid).then(userinfo => {
            const wxUserInfo = JSON.parse(userinfo.user_info)

            return AuthDbService.saveUserInfo(wxUserInfo, skey, session_key)
            .then(userinfo => ({
                loginState: LOGIN_STATE.SUCCESS,
                userinfo: {
                    userinfo: wxUserInfo,
                    skey: userinfo.skey
                }
            }))
        })
    })
}

【getUserInfoByOpenId方法对应的部分代码】

/**
 * 通过 openid 获取用户信息
 * @param {string} openid 用户的 openid
 */
function getUserInfoByOpenId (openId) {
    if (!openId) throw new Error(ERRORS.DBERR.ERR_NO_OPENID_ON_CALL_GETUSERINFOFUNCTION)

    return mysql('cSessionInfo').select('*').where({ open_id: openId }).first()
}

【疑问&求助】
同样server代码,在腾讯云免费开发环境就正常,本地调试的时候就报错,看起来是从cSessionInfo中没有查询到数据,,,
感觉很奇怪:在该步骤前,似乎没调用过AuthDbService.saveUserInfo……如果确实是这样,那cSessionInfo里根本没有数据啊,AuthDbService.getUserInfoByOpenId必然报错啊,,,

还是我哪里看错了,求大神帮忙解答TAT

关于本地调试,信道问题

*** 如果购买了腾讯云小程序解决方案,配置项中 serverHost, tunnelServerUrl, tunnelSignatureKey, qcloudAppId, qcloudSecretId, qcloudSecretKey, wxMessageToken 由腾讯云自动下发到您的开发环境和生产环境上。

我在本地启动 node服务来调试信道

tunnelServerUrl
tunnelSignatureKey

不知道在哪找,在腾讯云管理平台找了好久没看到。

qcloudAppId
qcloudSecretId
qcloudSecretKey

这三个参数倒是找到了。

不支持mongodb?

SDK 暴露了 Mysql 的链接; 意思就是天然支持mysql, 不支持mongodb?
文档不够详细

API 文档有误

API 文档里的
const qcloud = require('qcloud-weapp-server-sdk')(options)
应该是
const qcloud = require('wafer-node-sdk')(options)

新旧版混在一起,看得有点懵

wafer的cos模块是不是有bug?

image
返回的url那个region变成了undefined

然后我看了源码
image
这个url跟实际的差很多 region map是没有必要的

是有别的用意吗?

返回的用户信息出现奇怪的错误

default
如图所示,用正确的openID调用AuthDbService.getUserInfoByOpenId(openid),返回的结果确实另一个人的userInfo。

这里要出错,只可能是saveUserInfo出错,而调用此函数只有两个地方:一个是首次登陆时根据解密数据存储,第二个是二次登陆调用getUserInfoByOpenId()后更新skey。

从逻辑上说,前者解密不会出错,而后者是必定是前者出错后才会跟着出错,可出错的事实就在眼前,实在令人费解,希望能帮忙解决这个致命的问题。

关于登录接口的问题

微信并不推荐开发者在一进入就获取用户的信息比如头像昵称等等,事实上我们也没有必要获取这些。但是我们需要获取用户的openID,登录接口却默认获取了用户的信息,可否把获取用户信息做成一个可选项?只获取openID

koa2 使用uploader报错

  async uploadImage(ctx){
      let result = await wafer.uploader(ctx.req)
      ctx.state.data = result.uploadFolder+result.name
  }

0|index    | warning: AppId has been deprecated, Please put it at the end of parameter Bucket(E.g: "test-1250000000").
0|index    | (node:7948) [DEP0013] DeprecationWarning: Calling an asynchronous function without callback is deprecated.

文件可以正常上传,但会报两个错误

cos上传之后的返回地址问题

imgUrl: `http://${config.cos.fileBucket}-${config.qcloudAppId}.cos${regionMap[config.cos.region]}.myqcloud.com/${imgKey}`,

如果指定了 uploadFolder , 这个地址是不是应该在域名后面加个 uploadFolder 的文件夹前缀?

另外,可否将各种参数单独返回回来可供用户自定义拼接url?举个例子,比如说有种场景是我希望用https的链接地址,返回的http协议的地址不能满足我的需求。

nodejs自行配置出错,版本问题?

我看的流程是下面这个链接里的,很详细,很棒,但是我的还是出了问题
https://github.com/tencentyun/wafer2-startup/wiki/%E8%87%AA%E8%A1%8C%E9%83%A8%E7%BD%B2
我腾讯云服务器的nginx要比教程里的高,教程是1.10 我的是1.14
教程里面给的yum的nodejs源在我服务器上直接被surpport到了版本v10
但是教程里面的node -v是v8.4.0
于是在服务器拷贝好的serve目录下,npm install时,r错误第一次出现,就是下面这个
npm ERR! notarget No matching version found for wafer-node-sdk@^1.4.1
我还以是不是对node版本有要求,于是又卸载并且yum clean all,重新安装了nodejs官网的二进制v8.4.0做了软链接到bin里。
这次node -v和教程里面一样了,都是v8.4.0 npm教程里没看到,我的是5.3.0
但是npm ERR! notarget No matching version found for wafer-node-sdk@^1.4.1 这个错误依然出现
我看在咱们这个node-sdk里,版本也确实已经迭代到了1.4.1
不知道问题出现在哪里,还望大佬能给方法让我继续摸索 :)
感激不尽!

authorization (req) 似乎有个逻辑bug

if (code && !encryptedData && !iv) {
        return getSessionKey(code).then(pkg => {
            const { openid, session_key } = pkg
            // 生成 3rd_session
            const skey = sha1(session_key)

            return AuthDbService.getUserInfoByOpenId(openid).then(userinfo => {
                const wxUserInfo = JSON.parse(userinfo.user_info)

                return AuthDbService.saveUserInfo(wxUserInfo, skey, session_key)
                .then(userinfo => ({
                    loginState: LOGIN_STATE.SUCCESS,
                    userinfo: {
                        userinfo: wxUserInfo,
                        skey: userinfo.skey
                    }
                }))
            })
        })
    }

代码中getUserInfoByOpenId()先于saveUserInfo()使用,那么其中getUserInfoByOpenId()返回的userinfo很可能是undefined,我就遇到这种情况。

关于mysql 的配置为啥没有时区配置项

开发中发现,用sdk中的mysql时返回的数据中时间和**时间差了8小时,我估计是knex的时区配置问题,所以问下,为啥关于mysql的配置项中没有时区的配置

登录后去拿login信息时失败

11:23:27.482 response.js:20 Catch Error: Error: ERR_SKEY_INVALID
at validation (/data/release/node-weapp-demo/node_modules/wafer-node-sdk/lib/auth/index.js:91:22)
at validationMiddleware (/data/release/node-weapp-demo/node_modules/wafer-node-sdk/lib/auth/index.js:139:12)
at dispatch (/data/release/node-weapp-demo/node_modules/koa-router/node_modules/koa-compose/index.js:44:32)
at next (/data/release/node-weapp-demo/node_modules/koa-router/node_modules/koa-compose/index.js:45:18)
at /data/release/node-weapp-demo/node_modules/koa-router/lib/router.js:346:16
at dispatch (/data/release/node-weapp-demo/node_modules/koa-router/node_modules/koa-compose/index.js:44:32)
at /data/release/node-weapp-demo/node_modules/koa-router/node_modules/koa-compose/index.js:36:12
at dispatch (/data/release/node-weapp-demo/node_modules/koa-router/lib/router.js:351:31)
at dispatch (/data/release/node-weapp-demo/node_modules/koa-compose/index.js:42:32)
at parseBody.then.body (/data/release/node-weapp-demo/node_modules/koa-bodyparser/index.js:74:14)

文件类型判断错误

在wafer2-node-sdk/lib/upload/ 目录下的index文件里面的fileType判断有问题,会把mp3格式的文件判断为webm格式

Jest testEnvironment node throw error

Jest testEnvironment node throw error

FAIL test/services/tmpl/user.test.js
● Test suite failed to run

ERR_INIT_SDK_LOST_CONFIG

  34 | // 初始化 SDK
  35 | // 将基础配置和 sdk.config 合并传入 SDK 并导出初始化完成的 SDK
> 36 | module.exports = qcloud(Object.assign({}, sdkConfig, configs));
     |                  ^
  37 |

  at init (node_modules/wafer-node-sdk/index.js:48:190)
  at Object.<anonymous> (src/qcloud.js:36:18)
  at Object.<anonymous> (src/services/tmpl/user.js:2:1)
  at Object.<anonymous> (test/services/tmpl/user.test.js:1:1)

wafer2-node-sdk拿到的昵称有可能是乱码

有两种模板消息发至服务号,都含有昵称字段。
其中一种模板消息的昵称从数据库里取的,在服务号收到消息里昵称显示正常。
另一种模板消息的昵称是从ctx.state.$wxInfo.userinfo里取的,如果用户昵称包含有表情的话,会有一定的概率出现乱码(黑色方块,中间是问号)。

新版wafer2-node-sdk刷新用户信息的问题

在测试wafer2-node-sdk 1.4.1版本时发现,初次登录时的微信昵称会一直存在数据库里,后续即使更改了微信昵称,进行qcloud.login()/qcloud.loginWithCode()操作都不能更新用户信息。

lib mysql knex 连接初始化漏掉了timezone 信息

/lib/mysql/index 中 knex connection 初始化信息如下
module.exports = require('knex')({
client: 'mysql',
connection: {
host: configs.mysql.host,
port: configs.mysql.port,
user: configs.mysql.user,
password: configs.mysql.pass,
database: configs.mysql.db,
charset: configs.mysql.char
}
})

其中缺少 timezone 配置,应该添加配置 timezone: 'UTC'。否则使用使用这个配置返回的timestamp 内容会被自动回退8个小时,导致时间错误。请验证。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.