最近做一个新项目接触到和微信网页授权有关的两方面的内容:
1. 分享链接, 自定义标题、描述、分享图片。
2. 网页授权获取用户的信息。
第一个接口已经完成了,是直接调用其他人写好的现成的接口,而我们服务端只是做了一个透传,数据给到前端,其实目的就达到了。但是,调用的过程中会有很多疑问,比如接口是如何封装的?封装了哪些信息?access_token的刷新机制是什么?对我们来说是一个黑箱。后面还遇到了其他的问题,比如网页授权接口我们是要自己写还是依然调用理科的接口?他和之前分享链接的接口有没有联系?要解决这些疑问,还是要研究这两个功能到底是如何实现的。下面是根据开发过程整理出文档,记录下来,后续还有类似功能开发,可以借鉴。
1. 分享链接, 自定义标题、描述、分享图片。
文档地址:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
简单介绍:微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包。他提供了很多功能,我们这里使用的是分享功能,分享到微信,朋友圈。
概念:
a. access_token:access_token是公众号的全局唯一接口调用凭据, 公众号调用各接口时都需使用access_token。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。生成新token后,新旧access_token在5分钟内都有效。
b. jsapi_ticket: jsapi_ticket是公众号用于调用微信JS接口的临时票据, 通常有效期为7200秒,通过access_token来获取。
注意: 由于获取access_token和jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响业务,所以必须在服务全局缓存 。
开发步骤:
a. 获取access_token: access_token是公众号的全局唯一接口调用凭证,所以,保存到一个全局的位置。各应用程序使用的时候从全局获取即可。更新和刷新都是有全局统一操z作。
https请求方式: GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET grant_type是获取access_token填写client_credential
返回结果:
{"access_token":"ACCESS_TOKEN","expires_in":7200}
b.获取jsapi_ticket:jsapi_ticket是公众号用于调用微信JS接口的临时票据。有效期为7200秒。调用接口:
https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
成功返回如下JSON:
{ "errcode":0, "errmsg":"ok", "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA", "expires_in":7200 }
c. 获取签名
参与签名的参数有: 随机字符串noncestr, 时间戳timestamp, jsapi_ticket,业务url。
第一步:对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com?params=value
第二步:对string1进行sha1签名,得到signature:
0f9de62fce790f9a083d5c99e95740ceb90c27ed
第三步:返回签名信息
{ appId: '', timestamp: , nonceStr: '', signature: '', }
注意: 返回的参数中nonceStr和timestamp是第一步参与签名的nonceStr和timestamp
以上操作都是在服务端完成。下面的操作是在客户端完成
第四步:在分享页面引入微信js文件(支持https):http://res.wx.qq.com/open/js/jweixin-1.6.0.js
第五步:通过config接口注入权限验证配置
wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: '', // 必填,公众号的唯一标识 timestamp: , // 必填,生成签名的时间戳 nonceStr: '', // 必填,生成签名的随机串 signature: '',// 必填,签名 jsApiList: [] // 必填,需要使用的JS接口列表 });
备注: 这里的appId,timestamp,nonceStr,signature就是在第三步返回的值。
第六步:通过ready接口处理成功验证
wx.ready(function(){ // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。 });
第七步:通过error接口处理失败验证
wx.error(function(res){ // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。 });
第八步:判断当前客户端版本是否支持指定JS接口
wx.checkJsApi({ jsApiList: ['chooseImage'], // 需要检测的JS接口列表,所有JS接口列表见附录2, success: function(res) { // 以键值对的形式返回,可用的api值true,不可用为false // 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"} } });
第九步:分享给朋友
wx.ready(function () { //需在用户可能点击分享按钮前就先调用 wx.updateAppMessageShareData({ title: '', // 分享标题 desc: '', // 分享描述 link: '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致 imgUrl: '', // 分享图标 success: function () { // 设置成功 } }) });
第十步:分享到朋友圈
wx.ready(function () { //需在用户可能点击分享按钮前就先调用 wx.updateTimelineShareData({ title: '', // 分享标题 link: '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致 imgUrl: '', // 分享图标 success: function () { // 设置成功 } }) });
在这里就实现了分享链接自定义标题,和图片。如果不操作这个,会怎么样呢?分享出去就是一个url的地址。这种方式可以有更好地用户体验, 也更好的吸引用户的眼球。
2. 网页授权获取用户的信息。
文档地址:
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html#3
功能介绍:如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。
概念说明:
1)code: 用户同意授权后微信返回的code,这个code是获取网页授权access_token的票据。
2) access_token:这里的access_token是网页授权access_token, 与基础的access_token是不同的。
网页授权的方式:
网页授权的方式有两种:一种是静默授权,另一种是显示授权
1) 静默授权: scope值设置为snsapi_base, 只获取用户的openid, 对用户无感知。
2) 显示授权: scope值设置为snsapi_userinfo, 可以获取用户openid,以及用户的基本信息, 需要用户手动同意。
网页授权流程
备注: 本次我们使用的是静默授权,这里写出静默授权的试下步骤。
第一步:用户同意授权,获取code
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect 若提示“该链接无法访问”,请检查参数是否填写错误,是否拥有scope参数对应的授权作用域权限。
第二步:通过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" }
如果网页授权的作用域为snsapi_base,则本步骤中获取到网页授权access_token的同时,也获取到了openid。snsapi_base式的网页授权流程即到此为止。
我们本次需求调用的就是静默授权,所以执行到这里就可以了。
总结: 现在看,我们都只是调用已经写好的接口,做了一个透传, 但并不知道接口是如何实现的。这样一梳理,就知道了整个流程,后面在对接的时候也就清晰明确了。