前言
微信公众号对接第三方开发的前提就是授权. 首先是开通开放平台. 开通时填写资料包括公司信息, 还需要 300 大洋. 开放平台包括移动应用, 网站应用, 公众号账号, 小程序, 第三方平台. 这里我们开通第三方平台.
开通第三方平台时填写基本信息, 比如平台名称, 平台介绍, 平台图片. 下一步是选择权限集, 开发资料. 权限集就是托管公众号的功能, 比如回复消息, 创建菜单, 会话管理等等. 开发资料这里有 3 个地方需要注意, 授权事件接收 url, 授权测试公众号列表, 公众号消息于事件接收 url. 授权测试公众号列表主要是在全网发布之前, 在列表内的公众号才能进行授权.
一键授权给第三方平台
先来看一下官方提供的流程图, 有一个直观的认识.
授权官方提供了两种方式, 授权注册页面扫码授权, 点击移动端链接快速授权. 这里我用的是第一种, 在自己的页面上放一个链接, 点击后会生成一个二维码让公众号管理员扫码授权. https://mp.weixin.qq.com/cgi-bin/componentloginpage?component\_appid=xxxx&pre\_auth\_code=xxxxx&redirect\_uri=xxxx&auth\_type=xxx.
这里看到了链接路径包括包括 4 个参数. 前 3 个是必填. component_appid 是第三方平台的 appid,redirect_uri 是你需要用来获取授权信息的 url. 同意授权后微信服务器会请求这给地址. 到这里绕了一圈还有一个参数 pre_auth_code. 这个参数怎么获取? 这里先看一下官方文档 https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1453779503&token=&lang=zh_CN . 这里就该使用创建第三方平台时填写的授权事件 url 了. 微信服务器会每隔 10 分钟向改地址发起请求, 接收到的消息是密文, 需要自己解密, 官方已经提供了 demo, 可以参考. pre_auth_code 就要从这里的密文消息中获取.
用下面这个示意图来消化一下. 分 3 步来获取预授权码
获取 component_verify_ticket
获取 component_access_token
这里注意一下, 获取 component_access_token 参数是 JSON 字符串, 在对接第三方平台开发时这两个参数至关重要. component_verify_ticket 是公众平台和第三方平台沟通的桥梁. 这两个参数可以根据自己的需要保存在数据库或者 Redis 里. 后续调用其他高级接口和网页授权时都需要用到.
获取预授权码 (pre_auth_code)
知道了具体获取的方法, 那我们就看下具体的处理方法, 第一步先获取 verify_ticket.
- string sToken = "第三方平台 token";
- string sAppID = "第三方平台 appid";
- string sEncodingAESKey = "第三方平台 aeskey";
- WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sAppID);
- if (Request.HttpMethod.ToLower() == "post")
- {
- string sig = Request.QueryString["msg_signature"];
- string timestamp = Request.QueryString["timestamp"];
- string nonce = Request.QueryString["nonce"];
- StreamReader sr = new StreamReader(Request.InputStream, Encoding.UTF8);
- string respData = sr.ReadToEnd();
- string sMsg = ""; // 解析之后的明文
- int ret = 0;
- ret = wxcpt.DecryptMsg(sig, timestamp, nonce, respData, ref sMsg);
- if (ret != 0)
- {
- return;
- }
- XmlDocument doc = new XmlDocument();
- doc.LoadXml(sMsg);
- string infotype = doc.SelectSingleNode("xml").SelectSingleNode("InfoType").InnerText;
- string componentVerifyTicket = doc.SelectSingleNode("xml").SelectSingleNode("ComponentVerifyTicket").InnerText;
- switch (infotype)
- {
- case "component_verify_ticket":
- LogHelper.Info("ticket:" + componentVerifyTicket);// 这里就拿到了 component_verify_ticket
- Response.Write("success");
- Response.End();
- break;
- case "unauthorized":// 用户取消授权
- Response.End();
- break;
- }
- }
第二步获取 componet_access_token
- private static ResponseComponentToken GetComponentToken(string appid,string appsecret,string verifyticket)
- {
- var urlFormat = "https://api.weixin.qq.com/cgi-bin/component/api_component_token";
- object data = null;
- data = new
- {
- component_appid = appid,
- component_appsecret = appsecret,
- component_verify_ticket = verifyticket
- };
- return CommonJsonSend.Send<ResponseComponentToken>("", urlFormat, data);
- }
OK. 这里 pre_auth_code 就不罗列了, 可以用程序调, 也可以用 postman 调用.
到这里, 拿到 pre_auth_code 就可以点击上面的授权地址生成二维码, 扫码. 授权结束. 有点费劲!!!
代公众号网页授权
对接第三方平台后, 网页授权还是分为两种方式, 静默方式只能拿到 openid, 需要用户授权的可以拿到更多的用户信息. 实现方式相比公众号略有不同:
这里做开发时我用 senparc SDK, 参数包括公众号 appid, 第三方平台 appid, 第三方平台 accesstoken.
OAuthAccessTokenResult result = OAuthApi.GetAccessToken(appid, compAppid, compAccessToken, code);
代公众号处理消息和事件
创建第三方平台时填写了消息和事件接收 url. 第三方平台会把用户和微信互动的消息和事件转发到次 url. 也就是在这里你可以处理具体的消息和事件, 比如关注, 取消关注, 发送文本消息, 图片消息. 这里和公众号处理消息不同的地方在于回复用户的消息全部要加密. 加密方式同 verify_ticket 获取.
这里不需要再自己封装互动的消息和事件. 直接用 senparcSDK 的 CustomerMessageHandler 处理即可. 最后回复用户消息时需要用到加密消息: FinalResponseDocument. 可以参考 senparcSDK demo.
- if (Request.HttpMethod.ToLower() == "post")
- {
- var postModel = new PostModel()
- {
- Signature = Request.QueryString["signature"],
- Msg_Signature = Request.QueryString["msg_signature"],
- Timestamp = Request.QueryString["timestamp"],
- Nonce = Request.QueryString["nonce"],
- EncodingAESKey = sEncodingAESKey,
- Token = sToken,
- AppId = sAppID
- };
- var maxRecordCount = 10;
- var messageHandler = new CustomMessageHandler(Request.InputStream, postModel, maxRecordCount);
- try
- {
- //messageHandler.RequestDocument.Save(
- // Server.MapPath("~/App_Data/" + DateTime.Now.Ticks + "_Request_" +
- // messageHandler.RequestMessage.FromUserName + ".txt"));
- messageHandler.Execute();// 执行微信处理过程 (关键)
- //messageHandler.ResponseDocument.Save(
- // Server.MapPath("~/App_Data/" + DateTime.Now.Ticks + "_Response_" +
- // messageHandler.ResponseMessage.ToUserName + ".txt"));
- Response.Output.Write(messageHandler.FinalResponseDocument.ToString());
- //Response.Write("success");
- return;
- }
- catch (Exception ex)
- {
- LogHelper.Error(ex.Message,ex);
- }
- finally
- {
- Response.End();
- }
- }
参考资料
- http://www.cnblogs.com/szw/archive/2013/05/14/weixin-course-index.html
- https://www.cnblogs.com/sujingnan/p/4418882.html
- http://www.cnblogs.com/iCoffee/p/4815746.html
来源: https://www.cnblogs.com/sword-successful/p/10223734.html