微信开发学习
简单的介绍一下微信开发的一些注意事项
什么是OpenID,UnionID
做微信开发,绕不过两个名词 OpenID,UnionID
- OpenID
获取OpenID是我们在做微信开发必须要做的一件事情,OpenID就理解成用户的唯一标识
- UnionID
如果需要在多公众号、移动应用之间做用户共通,则需前往微信开放平台,将这些公众号和应用绑定到一个开放平台账号下
绑定后,一个用户虽然对多个公众号和应用有多个不同的OpenID,但他对所有这些同一开放平台账号下的公众号和应用,
只有一个UnionID,可以在用户管理-获取用户基本信息(UnionID机制)
什么是Access token
access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。
公众号和小程序均可以使用AppID和AppSecret调用本接口来获取access_token。AppID和AppSecret可在“微信公众平台-开发-基本配置”页中获得。
调用接口时,请登录“微信公众平台-开发-基本配置”提前将服务器IP地址添加到IP白名单中,点击查看设置方法,否则将无法调用成功。
网页授权(公众号)
接下来看看如何授权
1 | let link = window.location.href; |
通过代码可以看出,公众号使用跳转的方式进行网页授权,获取到用户的code,后端通过code,获取用户的openid
关于网页授权的两种scope的区别说明
以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)
以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。
用户管理类接口中的“获取用户基本信息接口”,是在用户和公众号产生消息交互或关注后事件推送后,才能根据用户OpenID来获取用户基本信息。这个接口,包括其他微信接口,都是需要该用户(即openid)关注了公众号后,才能调用成功的。
关于特殊场景下的静默授权
为什么我们的项目,使用的是snsapi_userinfo,也没有弹出授权?
上面已经提到,对于以snsapi_base为scope的网页授权,就静默授权的,用户无感知;
对于已关注公众号的用户,如果用户从公众号的会话或者自定义菜单进入本公众号的网页授权页,即使是scope为snsapi_userinfo,也是静默授权,用户无感知。
对于公众号授权步骤,分为四步
引导用户进入授权页面同意授权,获取code
通过code换取网页授权access_token(与基础支持中的access_token不同)
如果需要,开发者可以刷新网页授权access_token,避免过期
通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)
注意点
这里强调一下开发中可能会遇到的问题
- 回调的链接问题
若提示“该链接无法访问”,请检查参数是否填写错误,是否拥有scope参数对应的授权作用域权限。
由于授权操作安全等级较高,所以在发起授权请求时,微信会对授权链接做正则强匹配校验,如果链接的参数顺序不对,授权页面将无法正常访问
跳转回调redirect_uri,应当使用https链接来确保授权code的安全性。
回调的链接不支持 hash模式,需要做特殊处理
1 | let href = ''; |
- 获取access_token问题
通过code获取access_token,微信公众号配置IP白名单,才可以进行请求
由于公众号的secret和获取到的access_token安全级别都非常高,必须只保存在服务器,不允许传给客户端。后续刷新access_token、通过access_token获取用户信息等步骤,也必须从服务器发起。
拉取用户信息(需scope为 snsapi_userinfo)
如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和openid拉取用户信息了。
到这里,公众号完成了基本的网页授权
公众号使用微信JS-SDK
JSSDK使用步骤
绑定域名
先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
备注:登录后可在“开发者中心”查看对应的接口权限。
引入JS文件
在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.6.0.js
也可以直接导入npm包
首先安装 weixin-js-sdk, 之后引入进来 import wx from ‘weixin-js-sdk’也可以使用微信浏览器自带的方法(WeixinJSBridge)
通过config接口注入权限验证配置
所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用
1 | wx.config({ |
通过ready接口处理成功验证
1 | wx.ready(function(){ |
通过error接口处理失败验证
1 | wx.error(function(res){ |
到这里,微信公众号的JS-SDK就可以正常使用了,分享功能,音频接口,指纹识别,微信支付等可以在其他的博客看到使用的详细方法,更多的可以看看官方文档
小程序授权(微信小程序)
在说到小程序之前,先说一下它和公众号的区别
网页开发者可以使用到各种浏览器暴露出来的 DOM API,进行 DOM 选中和操作.
而小程序的逻辑层和渲染层是分开的,逻辑层运行在 JSCore 中,并没有一个完整浏览器对象,因而缺少相关的DOM API和BOM API。
运行环境
各平台脚本执行环境以及用于渲染非原生组件的环境是各不相同的:
在 iOS、iPadOS 和 Mac OS 上,小程序逻辑层的 javascript 代码运行在 JavaScriptCore 中,视图层是由 WKWebView 来渲染的,环境有 iOS 14、iPad OS 14、Mac OS 11.4 等;
在 Android 上,小程序逻辑层的 javascript 代码运行在 V8 中,视图层是由基于 Mobile Chrome 内核的自研 XWeb 引擎来渲染的;
在 Windows 上,小程序逻辑层 javascript 和视图层 javascript 都是用 Chrome 内核;
在 开发工具上,小程序逻辑层的 javascript 代码是运行在 NW.js 中,视图层是由 Chromium Webview 来渲染的。
运行环境 | 逻辑层 | 渲染层 |
---|---|---|
iOS | JavaScriptCore | WKWebView |
安卓 | V8 | chromium定制内核 |
小程序开发者工具 | NWJS | Chrome WebView |
由于视图渲染的方式不一致,还是建议开发者需要在 iOS 和 Android 上分别检查小程序的真实表现
除了样式的差异,在js上也有一定的区别
Promise 时序差异
由于实现原因与 iOS JavaScriptCore 限制,iOS 环境下的 Promise 是一个使用 setTimeout 模拟的 Polyfill。这意味着 Promise 触发的任务为普通任务,而非微任务,进而导致 在 iOS 下的 Promise 时序会和标准存在差异。
具体的宏任务和微任务的差别,这里不细讲了,博客的其他文章中有
登录流程
回归正传,看看小程序的授权流程,上图
微信小程序的登录比较简单,简单来说只有几步
- 调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
- 调用 auth.code2Session 接口,换取 用户唯一标识 OpenID 、用户在微信开放平台帐号下的唯一标识UnionID 和 会话密钥 session_key。
授权
部分接口需要经过用户授权同意才能调用。我们把这些接口按使用范围分成多个scope,用户选择对scope来进行授权,当授权给一个 scope 之后,其对应的所有接口都可以直接使用。
scope | 对应接口 | 描述 |
---|---|---|
scope.userInfo | wx.getUserInfo | 用户信息 |
scope.userLocation | wx.getLocation, wx.chooseLocation | 地理位置 |
scope.userLocationBackground | wx.startLocationUpdateBackground | 后台定位 |
scope.werun | wx.getWeRunData | 微信运动步数 |
scope.record | wx.startRecord | 录音功能 |
scope.writePhotosAlbum | wx.saveImageToPhotosAlbum, wx.saveVideoToPhotosAlbum | 保存到相册 |
scope.camera | camera 组件 | 保存到相册 |
此类接口调用时:
- 如果用户未接受,会弹窗询问用户,用户点击同意后方可调用接口;
- 如果用户已授权,可以直接调用接口;
- 如果用户已拒绝授权,则不会出现弹窗,而是直接进入接口 fail 回调。请开发者兼容用户拒绝授权的场景。
开发者可以使用 wx.getSetting 获取用户当前的授权状态。然后判断用户是否拒绝授权,弹窗二次提醒用户是否授权,开发者可以调用 wx.openSetting 打开设置界面,引导用户开启授权。
openSetting接口调整
getUserInfo接口调整
getLocation接口调整
需要注意的是, getUserProfile获取用户昵称头像等,需要用户手动触发,每次调用都会弹窗
获取手机号
因为需要用户主动触发才能发起获取手机号接口,所以该功能不由 API 来调用,需用 button 组件的点击来触发。
需要将 button 组件 open-type 的值设置为 getPhoneNumber,当用户点击并同意之后,可以通过 bindgetphonenumber 事件回调获取到微信服务器返回的加密数据, 然后在第三方服务端结合 session_key 以及 app_id 进行解密获取手机号。
1 | <button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"></button> |
在回调中调用 wx.login 登录,可能会刷新登录态。此时服务器使用 code 换取的 sessionKey 不是加密时使用的 sessionKey,导致解密失败。建议开发者提前进行 login;或者在回调中先使用 checkSession 进行登录态检查,避免 login 刷新登录态。
注意点
上传图片,下载,地图等功能,需要服务器配置安全域名
地图有的时候需要用到
https://apis.map.qq.com
,也要配置域名
如果项目中有用到web-view组件,H5的链接需要配置业务域名,配置时校验文件需要放在域名的根目录
服务器域名配置
服务器域名请在 「小程序后台-开发-开发设置-服务器域名」 中进行配置,配置时需要注意:
- 域名只支持 https (wx.request、wx.uploadFile、wx.downloadFile) 和 wss (wx.connectSocket) 协议;
- 域名不能使用 IP 地址(小程序的局域网 IP 除外)或 localhost;
- 域名必须经过 ICP 备案;
- 出于安全考虑,api.weixin.qq.com 不能被配置为服务器域名,相关API也不能在小程序内调用。 开发者应将 AppSecret 保存到后台服务器中,通过服务器使用 getAccessToken 接口获取 access_token,并调用相关 API;
- 不支持配置父域名,使用子域名。
HTTPS 证书
小程序必须使用 HTTPS/WSS 发起网络请求。请求时系统会对服务器域名使用的 HTTPS 证书进行校验,如果校验失败,则请求不能成功发起。由于系统限制,不同平台对于证书要求的严格程度不同。为了保证小程序的兼容性,建议开发者按照最高标准进行证书配置,并使用相关工具检查现有证书是否符合要求。
对证书要求如下:
- HTTPS 证书必须有效;
- 证书必须被系统信任,即根证书被已系统内置
- 部署 SSL 证书的网站域名必须与证书颁发的域名一致
- 证书必须在有效期内
- 证书的信任链必需完整(需要服务器配置)
- iOS 不支持自签名证书;
- iOS 下证书必须满足苹果 App Transport Security (ATS) 的要求;
- TLS 必须支持 1.2 及以上版本。部分旧 Android 机型还未支持 TLS 1.2,请确保 HTTPS 服务器的 TLS 版本支持 1.2 及以下版本;
- 部分 CA 可能不被操作系统信任,请开发者在选择证书时注意小程序和各系统的相关通告。
- Chrome 56/57 内核对 WoSign、StartCom 证书限制周知
(…未完待续)