【企微开发最佳实践】自建应用服务端开发如何调试回调?

2022/11/08
发布

 社区经常有人问自建应用的回调调试应该怎么处理?受限于官方的内网穿透工具目前还不支持自建应用。这里分享下调试方法!


   三方和代开发应用可以参考 内网穿透工具 使用官方的内网穿透工具进行回调调试。


    目前要实现自建应用本机回调调试的前提条件:

  • 一台外网可访问的机器
  • 一个已经绑定过可信域名的应用
  • 应用可配置可信IP(非必需,如果本地会调用企业微信接口是需要添加本地IP的)


   服务端的回调可以用到的方式可以有如下几种(仅为个人观点):

  • 服务器上配置ngx_http_mirror_module,把流量打回开发机器;但一般受限于办公室的网络需要做一些配置啥的,操作起来较困难
  • 在外网机器上配置开发环境,使用vscode之类的工具连接远程环境开发(大多数不会有这么高的待遇)
  • 把回调内容写日志,拿到日志内容在本地模拟回调

 本文主要讲最后一种,先上样例代码:

package main

import (
  "github.com/gin-gonic/gin"
  "github.com/go-laoji/wxbizmsgcrypt"
  "io/ioutil"
  "log"
  "net/http"
)

const (
  TOKEN  = ""                     //修改成自己配置的token
  AESKEY = ""                     //修改成自己的aeskey
  CORPID = ""                     //修改成自己的企业ID
)

type QueryParams struct {
  MsgSignature string `form:"msg_signature"`
  TimeStamp    string `form:"timestamp"`
  Nonce        string `form:"nonce"`
  EchoStr      string `form:"echostr"`
}

func main() {
  router := gin.Default()
  wxbiz := wxbizmsgcrypt.NewWXBizMsgCrypt(TOKEN,
    AESKEY,
    CORPID,
    wxbizmsgcrypt.XmlType)
  router.GET("/callback", func(c *gin.Context) {
    var q QueryParams
    if ok := c.Bind(&q); ok == nil {
      echoStr, err := wxbiz.VerifyURL(q.MsgSignature, q.TimeStamp, q.Nonce, q.EchoStr)
      if err != nil {
        c.JSON(http.StatusNotImplemented, gin.H{"error": err.ErrMsg})
      } else {
        c.Writer.Write(echoStr)
      }
    }
  })
  router.POST("/callback", func(c *gin.Context) {
    var q QueryParams
    if ok := c.Bind(&q); ok == nil {
      body, e := ioutil.ReadAll(c.Request.Body)
      if e != nil {
        log.Fatal(e)
      } else {
        // 用来记录Post的过来的原始数据
        log.Println(string(body))
      }
      msg, err := wxbiz.DecryptMsg(q.MsgSignature, q.TimeStamp, q.Nonce, body)
      if err != nil {
        log.Fatal(err.ErrMsg)
      } else {
        // 输出解密后的消息内容
        log.Println(string(msg))
        // TODO:实现自己的业务逻辑
      }
      c.Writer.WriteString("success")
    } else {
      c.AbortWithStatus(http.StatusNotImplemented)
    }
  })

  router.Run(":8888")
}

代码实现一个 /callback的路由,支持get和post两个方法,分别对应应用配置回调时的get验证;post的数据回调,49行这里把body的内容做记录打印,这就是后面模拟数据的payload。54-58行这中间是要去实现自己的业务逻辑!


调试过程

    1、把服务部署到外网服务器上,使回调测试能通过。下面模拟一个发送消息给应用的回调过程(主要这个用例太好实现了,像测试添加联系人啥的还得去添加操作)。

   发送个消息给应用

图片

服务器控制台输出的消息格式如下:

<xml><ToUserName><![CDATA[你的企业ID]]></ToUserName><Encrypt><![CDATA[zZRTOi3htkqSNOwzxKc0HT+WXTkmXuYBTn3Sd1t6/P++//oPNwCLW4UXaJZ052Cd0tqRa2+cte2KT4zb/+b3v75aWRpNhzaZqnnWrtlGg84MQnWC/is1+6uDmQ9LweOutj7aTnph/iwgVM6NY+DruZk3gD+QFEccktaFd+B+/C3JWHHdmPeVloXknViki7GJ9YKZGnlx1gvhNawUsVlIogp7Vfm9Kr1oOWnn6VUe4bbgXw08YselifYLlwth3BZ8Q7Mc6pHdRDX+saWMKx43bWOMu6KFIT3Qy+EJZUIDnWDzFXbYxLM8K2/I79wdgxKXx8knkAvpWbP20PiL1Zrhd3xdQ4LugHpwDj5T4wGF6GhsbS3pd8CWvKh1ejwTKXPQSWVIWvp8Y+9jz2AWarD1s4wkU34LWjOjHZ8rCsWf9fQ=]]></Encrypt><AgentID><![CDATA[你的应用id]]></AgentID></xml>

请求的url可以在web日志中看到:

/callback?msg_signature=d7ad4116996b432cd4ea60160a911249c7758011&timestamp=1667876730&nonce=1668281536

2、利用apifox进行模拟,先配置请求参数

图片

再配置 body内容

图片

测试环境配置本地环境默认服务地址:http://127.0.0.1:8888,运行输出

图片

3、再看服务端的单步调试

图片


apifox的配置共享链接 https://www.apifox.cn/apidoc/shared-14fdcc37-3ff0-46cd-bd2a-3b2c201cbc0a


本文只做抛砖引玉,有更好的调试方法可以给回复进行分享!

评论·1
2022/11/11

还是个golang小伙

赞同
评论 1
2022/11/18
已经是大叔了...
赞同
回复
你还未登录,请先登录