微信H5开发历程记录

wechat

登录授权

  • 微信OAuth:在微信下使用oauth进行用户授权,以便获取用户信息,服务端要配置appID和secret,当用户进入H5页面时候,发现没有授权,就引导用户进行跳转链接授权,这时候会跳转url到
1
https://open.weixin.qq.com/connect/oauth2/authorize?appid=${config.appId}&redirect_uri=${encodeURIComponent(config.redirectUrl)}&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect

redirectUrl是表示授权后的回调路由跳转,然后回调路由微信会在url里面注入code和state,凭借code和state后端可以向微信获取用户的access_token,要获取用户信息,要使用access_token

  • 向微信请求用户信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import nconf from 'nconf'
import Promise from 'bluebird'
const request = Promise.promisifyAll(require('request'));

const getToken = async (code) => {
const url = `${nconf.get('wechat:baseUrl')}/sns/oauth2/access_token?appid=${nconf.get('wechat:appId')}&secret=${nconf.get('wechat:appSecret')}&code=${code}&grant_type=authorization_code`;
const res = await request.getAsync({
url,
json: true
})
const body = res.body
if (!body.access_token) {
return Promise.reject(new Error(body.errcode +'/'+ body.errmsg))
}
return body
}
const getUserInfo =async (token, openid) => {
const url = `${nconf.get('wechat:baseUrl')}/sns/userinfo?access_token=${token}&openid=${openid}&lang=zh_CN`
const res = await request.getAsync({
url,
json: true
})
const body = res.body
if(!body.openid) {
return Promise.reject(new Error(body.errcode +'/'+ body.errmsg))
}
return body
}

export {
getToken,
getUserInfo
}

配置

  • JS-SDK设置:微信的js-sdk调用比较简单,但是配置需要注意安全域名

安全域名
切记:只能填写域名或者ip,不要多加其他字段

安全域名
切记:这个地方还要设置安全域名,坑爹!一开始不知道

  • 微信的js-sdk需要config,这时候需要服务器提供签名认证,使用wechat-api自动获取access_token(注意保存,不能多次频繁获取)

服务器认证

服务器

微信需要对你的服务器进行认证,你的服务器需要进行http或者https的响应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { exchangeToken, getJSConfig } from '../controllers/wechat';
import nconf from 'nconf'
const crypto = require("crypto");

module.exports = (router, commonRouter, authRouter, wechatRouter) => {
wechatRouter.post('/exchangeToken', exchangeToken);
wechatRouter.get('/getJSConfig', getJSConfig);
wechatRouter.get('/', function(req, res) {
let signature = req.query.signature,
timestamp = req.query.timestamp,
nonce = req.query.nonce,
echostr = req.query.echostr;
let array = [nconf.get('wechat:token'), timestamp, nonce];
array.sort();
let tempStr = array.join("");
const hashCode = crypto.createHash("sha1");
let resultCode = hashCode.update(tempStr, "utf8").digest("hex");
if (resultCode === signature) {
res.send(echostr);
} else {
res.send("mismatch");
}
});
};

要点注意

  • vue.js History路由和后台接口冲突问题:vue前端路由push一个路由可以正常跳转,但是如果路由直接复制到浏览器或者刷新就会和后端的服务接口发生冲突,解决方法是对nginx进行url强制转化

  • vue.js Hash路由在微信授权跳转回来的时候由于带有#的原因,导致注入code和state会在#前面,无法用this.$route.query来获取,需要使用window.location.href自行正则匹配获取

  • Nuxt服务端渲染由于是第一次加使用后端直出的模版,但是当前端路由跳转后,就不是又后端直出了,而是使用前端的bundle文件进行渲染,在ios不会出现js-sdk invalid url的错误,但是在安卓下就会出错,而且js-sdk不能配置多次,一个页面进去只能配置一次,而且需要在wx.ready的回调方法里面对微信的js-sdk接口进行配置和使用。解决方法是不使用nuxt的vue-router,而是使用window的location.href来路由跳转,不过这样性能不好,最好是不要在router-view的外层进行配置,而是单独对里面的子页面进行配置

  • H5下,音频播放问题,在ios下面,播放音频视频都需要用户去触发事件才能执行

  • 正式配置微信的服务号,设置安全域名需要上传一个文件,类似证书吧,这个路径微信写着要放置到web的根目录下面,原来所谓的web根目录就是静态服务器下面的public文件夹,一开始配置nginx root路径好久,发现没卵用。

  • 原来微信下每个公众号的对应用户的openid都是不一样的,在发送消息推送,以为和测试号的id一样,最后查了数据库发现不一致