微信小程序开发实践总结

1,582 阅读8分钟

1.小程序登录

小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系。

登录流程时序

说明:

  • 调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
  • 调用 auth.code2Session 接口,换取 用户唯一标识 OpenID 和 会话密钥 session_key。 之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。

注意:

  • 会话密钥 session_key 是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。
  • 临时登录凭证 code 只能使用一次

以上为微信小程序开发者文档中的内容,具体含义说的也比较清楚,当然了,对于很对刚入门的小年轻,估计还是有点不好理解,那么我再补充几点。

  • 一般情况下小程序开发者可以通过用户的登录行为,通过wx.login()方法获取到临时登录凭证code。这个临时登录凭证就可以作为参数登录后端提供的登录接口,该接口需要后端开发人员开发,其实就是做个中转,这个接口内部来请求腾讯提供的登录接口"https://api.weixin.qq.com/sns/jscode2session,这个接口就是文档中的auth.code2Session

  • auth.code2Session这个接口需要提供的参数有 appid(小程序的appId)、secret (小程序appSecret)、js_code(这个就是上面的临时登录凭证code)、grant_type是授权类型,在登录时,需要填入authorization_code

auth.code2Session会返回用户的唯一凭证openid以及会话密钥session_key,这个openid在此小程序平台上是一直不会变的。每次登录只有session_key会发送变化。

登录如果异常,会返回报错码errcode,以及错误信息errmsg,

常见的errcode值有

  • -1 :系统繁忙,此时请开发者稍候再试
  • 0 :请求成功
  • 40029 :code 无效
  • 45011 :频率限制,每个用户每分钟100次

2.订阅消息

第一步, 在微信公众平台手动配置获取模板 ID: 登录 https://mp.weixin.qq.com 获取模板,如果没有合适的模板,可以申请添加新模板,审核通过后可使用。

第二步, 获取下发权限 详见小程序端消息订阅接口 wx.requestSubscribeMessage

因为消息分为两种,一种为一次性消息推送和长期消息推送,不过目前好像长期的不多了。每次推送都需要获取用户的允许,否则微信会拦截消息的。

第三步,推送消息 在真正向用户推送消息之前,需要先获取ACCESS_TOKEN。这个东西在推送消息时,需要提供,而且限制不少。 这个东西需要调用如下接口来获取

GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

请求该接口需要提供grant_type使用client_credential即可,然后是小程序appId以及小程序密钥appSecret.

成功请求该接口将返回

  • access_token:这个就是获取到的凭证,后端开发人员需要妥善保存,并且在2个小时内进行自动刷新
  • expires_in:凭证的有效时间,单位为秒,目前是7200秒之内的值。也就是2个小时。

如果该接口请求异常,会报如下错误代码,以及错误信息

  • -1 :系统繁忙,此时请开发者稍候再试
  • 0 :请求成功
  • 40001 :AppSecret 错误或者 AppSecret 不属于这个小程序,请开发者确认 AppSecret 的正确性
  • 40002 :请确保 grant_type 字段值为 client_credential
  • 40013 :不合法的 AppID,请开发者检查 AppID 的正确性,避免异常字符,注意大小写

对于access_token有以下注意事项

  • access_token 的存储至少要保留 512 个字符空间;就是数据库保存的话,该字段需要至少512字符长度
  • access_token 的有效期目前为 2 个小时,需定时刷新,重复获取将导致上次获取的 access_token 失效;一般1个小时刷就够了。 建议开发者使用中控服务器统一获取和刷新 access_token,其他业务逻辑服务器所使用的 access_token 均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致 access_token 覆盖而影响业务; 这个非常重要,不要多个进程同时刷这个东西,否则就会有问题。
  • access_token 的有效期通过返回的 expires_in 来传达,目前是7200秒之内的值,中控服务器需要根据这个有效时间提前去刷新。在刷新过程中,中控服务器可对外继续输出的老 access_token,此时公众平台后台会保证在5分钟内,新老 access_token 都可用,这保证了第三方业务的平滑过渡;
  • access_token 的有效时间可能会在未来有调整,所以中控服务器不仅需要内部定时主动刷新,还需要提供被动刷新 access_token 的接口,这样便于业务服务器在API调用获知 access_token 已超时的情况下,可以触发 access_token 的刷新流程。

如果多实例的应用程序都在耍access_token,你会发现,这个时候,所有使用access_token的业务接口都会嗝屁了。

报如下错误,以为你的access_token已经不能用啦。

err_code:40001, err_msg:invalid credential, access_token is invalid or not latest rid: 5f703f3c-78c08784-6ee0c177

正在执行推送业务的,需要请求下面的接口

https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN

需要提供的参数有

属性类型默认值必填说明
access_tokenstring接口调用凭证
touserstring接收者(用户)的 openid
template_idstring所需下发的订阅模板id
pagestring点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。
dataObject模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } }
miniprogram_statestring跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
langstring进入小程序查看”的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN

接口返回:

  • errcode number 错误码

  • errmsg string 错误信息

  • 40003 touser字段openid为空或者不正确

  • 40037 订阅模板id为空不正确

  • 43101 用户拒绝接受消息,如果用户之前曾经订阅过,则表示用户取消了订阅关系

  • 47003 模板参数不准确,可能为空或者不满足规则,errmsg会提示具体是哪个字段出错

  • 41030 page路径不正确,需要保证在现网版本小程序中存在,与app.json保持一致

如果发现该接口返回40001,就要留意,是不是在该接口中提供的access_token,是不是被其他进行刷了,因为任何刷新前的access_token都是不能使用的。

对于该接口的请求示例:

{
  "touser": "OPENID",
  "template_id": "TEMPLATE_ID",
  "page": "index",
  "miniprogram_state":"developer",
  "lang":"zh_CN",
  "data": {
      "number01": {
          "value": "339208499"
      },
      "date01": {
          "value": "2015年01月05日"
      },
      "site01": {
          "value": "TIT创意园"
      } ,
      "site02": {
          "value": "广州市新港中路397号"
      }
  }
}

需要留意的是,在请求模板的时候,要看情况,模板字段的内容长度限制。否则内容过长,或者内容不合适,都是要报错的。

比如

argument invalid! data.thing2.value invalid rid: 5f588478-435e6014-1c126d75

就要看看,字段的值是不是超长了,或者为空了啥的。

当然了,如果用户没有允许推送消息,那么该接口也会报错。

user refuse to accept the msg rid: 5f64ade8-4ad74413-3f2bba80

最好就是针对每一条消息推送,都进行推送详情记录。防止在没有成功推送的情况下,无法排查失败的原因。

参数类别参数说明参数值限制说明
thing.DATA事物20个以内字符可汉字、数字、字母或符号组合
number.DATA数字32位以内数字只能数字,可带小数
letter.DATA字母32位以内字母只能字母
symbol.DATA符号5位以内符号只能符号
character_string.DATA字符串32位以内数字、字母或符号可数字、字母或符号组合
time.DATA时间24小时制时间格式(支持+年月日),支持填时间段,两个时间点之间用“~”符号连接例如:15:01,或:2019年10月1日 15:01
date.DATA日期年月日格式(支持+24小时制时间),支持填时间段,两个时间点之间用“~”符号连接例如:2019年10月1日,或:2019年10月1日 15:01
amount.DATA金额1个币种符号+10位以内纯数字,可带小数,结尾可带“元”可带小数
phone_number.DATA电话17位以内,数字、符号电话号码,例:+86-0766-66888866
car_number.DATA车牌8位以内,第一位与最后一位可为汉字,其余为字母或数字车牌号码:粤A8Z888挂
name.DATA姓名10个以内纯汉字或20个以内纯字母或符号中文名10个汉字内;纯英文名20个字母内;中文和字母混合按中文名算,10个字内
phrase.DATA汉字5个以内汉字5个以内纯汉字,例如:配送中