微信开放平台开发:用unionid打通网页应用 与 服务号 的用户数据关联

需求背景

采用微信登录的授权的 网页应用 需要用到 服务号 的模板下发功能

例如在某电商网页上进行了购买操作,需要相关联的服务号发送一条购买成功的模板消息。(如果关注了京东的服务号,每次在京东上买东西的时候会受到服务号下发模板消息)

需要达成效果如下:

image

实现思路

微信开发会遇到两种常见的用户ID,openid 和 unionid

每个用户对开放平台有唯一的unionid

每个用户对于每个服务号或者网页/APP应用有不同的openid

需要以unionid为桥梁打通 网页应用 和 服务号 的数据关联。

实现步骤

  1. 服务号和开放平台认证 并 服务号绑定开放平台。
  2. 用户在网页应用采用微信授权登录,授权成功后根据 code 获取用户 unionid
  3. 部署服务号消息订阅服务器,接受微信推送的事件消息(例如服务号关注事件,取消关注事件)
  4. 在用户关注公众号的时候,订阅服务器获取订阅用户的服务号openid
  5. 用服务号openid获取userinfo(用户信息),其中包括unionid
  6. 通过unionid确定用户身份,将服务号openid写入该用户表
  7. 在业务发生的时候,通过服务号openid直接下发模板消息。

网页应用授权

参考官方文档 https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=4d3543ff030ecd73c21923bd8426d08678986d88&lang=

第一步:请求CODE

步骤1:在页面中先引入如下JS文件(支持https):

http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js

步骤2:在需要使用微信登录的地方实例以下JS对象:

 var obj = new WxLogin({
 self_redirect:false,
 id:"login_container", 
 appid: "appid", 
 scope: "snsapi_login", 
 redirect_uri: "",
  state: "",
 style: "",
 href: ""
 });

步骤3: 用户在手机上确认授权后,页面会自动重定向到redirect_uri上,并且带上code和state参数。

第二步:通过code获取access_token

通过code获取access_token

直接调下面的接口即可

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

正确的返回结果如下:

{ 
"access_token":"ACCESS_TOKEN", 
"expires_in":7200, 
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID", 
"scope":"SCOPE",
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

获取用户信息

access_token 可以用来进一步获取用户公开信息(包括头像,名字,地理位置)

直接调下面的接口即可

https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

正确的返回消息如下

{
    "openid": "oAX1fwQevayrMNxAZGvoa8kvZCMc",
    "nickname": "Band",
    "sex": 1,
    "language": "zh_CN",
    "city": "Guangzhou",
    "province": "Guangdong",
    "country": "CN",
    "headimgurl": "http://thirdwx.qlogo.cn/mmopen/vi_32/4WFBCHqe458kAocTXqVPV5CHxHmYQs414DcqRqmC3jTZVYYqGvRbSgNYGRIeUaCge6r8AD6bcsU1RzfldGHJKg/132",
    "privilege": [
        "chinaunicom"
    ],
    "unionid": "oTq_VwExIiigeoJtP8r0FrQj7Cqk"
}

部署服务号消息订阅服务器

参考官方文档 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319

第一步: 填写服务器配置

登录微信公众平台官网后,在公众平台官网的开发-基本设置页面,勾选协议成为开发者,点击“修改配置”按钮,填写服务器地址(URL)、Token和EncodingAESKey,其中URL是开发者用来接收微信消息和事件的接口URL。Token可由开发者可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)。EncodingAESKey由开发者手动填写或随机生成,将用作消息体加解密密钥。

image

第二步:验证消息的确来自微信服务器

开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带参数如下表所示:

参数 描述
signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
timestamp 时间戳
nonce 随机数
echostr 随机字符串

开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。加密/校验流程如下:

1)将token、timestamp、nonce三个参数进行字典序排序 2)将三个参数字符串拼接成一个字符串进行sha1加密 3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

express 版本的验证代码

// var crypto = require('crypto');
// const hash = crypto.createHash('sha1')

var wxReceiver = function(req, res, next) {
    
    console.log('wxReceiver-body: ', req.body);
    
    const signature = req.query.signature
    const timestamp = req.query.timestamp
    const nonce = req.query.nonce
    const echostr = req.query.echostr
    
    const arr = [nonce, 'njjnjn', timestamp]
    arr.sort()
    
    const tStr = arr[0] + arr[1] + arr[2]
    hash.update(tStr)
    const hashResult = hash.digest('hex')
    
    if(hashResult == signature) {
        // 这是来自微信官方的消息
        res.send(echostr)
    }
};

依据接口文档实现业务逻辑

验证URL有效性成功后即接入生效,成为开发者。你可以在公众平台网站中申请微信认证,认证成功后,将获得更多接口权限,满足更多业务需求。

成为开发者后,用户每次向公众号发送消息、或者产生自定义菜单、或产生微信支付订单等情况时,开发者填写的服务器配置URL将得到微信服务器推送过来的消息和事件,开发者可以依据自身业务逻辑进行响应,如回复消息

消息是XML格式的,这是xml parse后的 消息模式长这样

   { 
        tousername: [ 'gh_15a5ec8f6116' ],
        fromusername: [ 'oC9vJwnxrquE5Ss2PEL49TX-3hpI' ],
        createtime: [ '1524646369' ],
        msgtype: [ 'event' ],
        event: [ 'TEMPLATESENDJOBFINISH' ],
        msgid: [ '252565859871080449' ],
        status: [ 'success' ] 
   } 

这里面fromusername就是服务号的openid

推送模板消息

官方文档 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277

这个功能需要审核才能用,审核之后先添加模板

然后直接调用接口即可发送模板消息

<!--http请求方式: POST-->
https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN

POST数据示例如下:

{
           "touser":"OPENID",
           "template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
           "url":"http://weixin.qq.com/download",  
           "data":{
                   "first": {
                       "value":"恭喜你购买成功!",
                       "color":"#173177"
                   },
                   "keyword1":{
                       "value":"巧克力",
                       "color":"#173177"
                   },
                   "keyword2": {
                       "value":"39.8元",
                       "color":"#173177"
                   },
                   "keyword3": {
                       "value":"2014年9月22日",
                       "color":"#173177"
                   },
                   "remark":{
                       "value":"欢迎再次购买!",
                       "color":"#173177"
                   }
           }
       }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容