1

上一篇:nodejs微信开发---授权登录+获取用户信息
这部分主要是js sdk的接入和调用。这里仅仅是接入成功的示例,更多详细的接口使用就不多说了,接下来用到的地方在做解释。
接入成功后效果如图:

clipboard.png

下面根据微信平台官方文档的步骤一步步来。

绑定域名和引入sdk

首先是绑定域名,这里的域名是指js安全域名,所有接口只能在这里调用。

clipboard.png

有一点要注意。域名是指主域名,不管多少层子域名,仅仅需要填写主域名。

通过config接口注入权限验证配置

所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。
也就是说想要调用js-sdk必须先进行验证。
验证步骤如下:

  1. 通过access_token获取jsapi_ticket,注意jsapi_ticket的有效期也是7200s,同样需要进行全局缓存。
    代码实现如下:

//getWebToken.js
'use strict';
const request = require('request');
const qs = require('querystring');
const config = require('../../config');

function getToken(code) {
  let reqUrl = 'https://api.weixin.qq.com/sns/oauth2/access_token?';
  let params = {
    appid: config.appId,
    secret: config.appSecret,
    code: code,
    grant_type: 'authorization_code'
  };

  let options = {
    method: 'get',
    url: reqUrl+qs.stringify(params)
  };
  console.log(options.url);
  return new Promise((resolve, reject) => {
    request(options, function (err, res, body) {
      if (res) {
        console.log(body)
        resolve(body);
      } else {
        reject(err);
      }
    })
  })
}

module.exports = getToken;
  1. 获得签名。参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义
    代码实习如下:

//getJsApiData.js
'use strict';
const fs = require('fs');
const request = require('request');
const qs = require('querystring');
const config = require('../../config');
const token = fs.readFileSync('./token').toString();
const sha1 = require('./util').sha1;
const reqUrl = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' + token + '&type=jsapi';

function getJsApiTicket() {
  let options = {
    method: 'get',
    url: reqUrl
  };

  return new Promise((resolve, reject) => {
    request(options, function (err, res, body) {
      if (res) {
        resolve(body);
      } else {
        reject(err);
      }
    })
  })
}
//noncestr
function getNonceStr () {
  var text = "";
  var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  for(var i = 0; i < 16; i++) {
    text += possible.charAt(Math.floor(Math.random() * possible.length));
  }
  return text;
}
//timestamp
function getTimestamp() {
  return new Date().valueOf();
}

function getSign(jsApiTicket, noncestr, timestamp, url) {
  let data = {
    'jsapi_ticket': jsApiTicket,
    'noncestr': noncestr,
    'timestamp': timestamp,
    'url': 'http://wuyrsp3tma.proxy.qqbrowser.cc/auth'
  };
  var sortData = "jsapi_ticket=" + jsApiTicket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url;
  console.log(sortData);
  return sha1(sortData);
}

//返回数据分别为sign, timestamp, noncestr
function getJsApiData(clientUrl) {
  let noncestr = getNonceStr();
  let timestamp = getTimestamp();
  return getJsApiTicket().then(data => {
    return [getSign(JSON.parse(data).ticket, noncestr, timestamp, clientUrl), timestamp, noncestr];
  })
}

module.exports = getJsApiData;

然后在路由传值得时候进行处理:

router.get('/auth', function (req, res) {
  var clientUrl = 'http://' + req.hostname + req.url;
  getJsApiData(clientUrl).then(data => {
    res.render('base.html', {signature: data[0], timestamp: data[1], nonceStr: data[2], appId: config.appId});
  });
});

将前端所需要的值传递过去。前端再进行相应的配置,注意这里使用了模板引擎,如果ajax取值也是一样的道理。

wx.config({
            debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
            appId: '{{appId}}', // 必填,公众号的唯一标识
            timestamp: '{{timestamp}}', // 必填,生成签名的时间戳
            nonceStr: '{{nonceStr}}', // 必填,生成签名的随机串
            signature: '{{signature}}',// 必填,签名,见附录1
            jsApiList: ['onMenuShareTimeline'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
        });

我们可以看到权限已经拿到手了。

clipboard.png

再进行一下接口测试:

//分享到朋友圈
wx.ready(function () {
    wx.onMenuShareTimeline({
        title: '测试', // 分享标题
        link: 'xiadd.me', // 分享链接
        imgUrl: '', // 分享图标
        success: function () {
            console.log('success');
        },
        cancel: function () {
            console.log('canceled')
        }
    });
})

可以看到,调用成功:

clipboard.png


xiadd
2.6k 声望88 粉丝