微信小程序云开发调用access_token调用微信公众号素材
文章 2397 0 0 0
发布时间:2020年01月04日

概述

在使用小程序api地址开发的时候我们通常不能使用官网的api地址直接在小程序中调用,想要使用他们的api就要我们通过统一后台调用以后返回给前台使用,不能直接使用的原因就是每个用户的ip都是不一样的我们总不能把所有的用户都绑定上白名单,我们只需要通过自己的域名去访问,让用户通过域名访问我们的自定义接口,那么我们就只需要绑定一个域名就行,在开发的时候只是从公众号掉取文章素材图文素材到小程序中,所以我们采用了云开发的方式来实现我们的功能!

前提:确认公众号的接口权限

在公众号接口权限中查看我们是否可以使用该接口

微信小程序云开发调用access_token调用微信公众号素材

一、配置白名单

把微信(https://api.weixin.qq.com)的ip加入到白名单中

微信小程序云开发调用access_token调用微信公众号素材

首先在云数据库中新建集合名称”access_token”,并新建字段_id、accessToken、createTime、expiresIn用来存储access_token值及有效时间。

微信小程序云开发调用access_token调用微信公众号素材

接口调用请求说明
https请求方式: GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

1、云开发控制台,新建集合wx-access-token,用于保存获取到的微信公众号的access_token

2、开发者工具 > 云函数目录 > 右键选择 “新建Node.js” 云函数 getAccessToken,如下图:

微信小程序云开发调用access_token调用微信公众号素材

在云函数中新建类AccessToken

const cloud = require('wx-server-sdk')
const request = require('request')
class AccessToken{
 constructor({ appid, secret}){
    this.appid=appid
    this.secret=secret
  }
}
module.exports=AccessToken

在AccessToken类中新建函数getAccessToken()用来获取access_token

// 获取 access_token

async getAccessToken() {
  let token_url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='+this.appid+'&'+'secret='+this.secret;
  const rp = options =>
    new Promise((resolve, reject) => {
      request(options, (error, response, body) => {
        if (error) {
          reject(error);
        }
        resolve(response);
      });
    });
  const result = await rp({
    url:token_url,
    method:'GET'
  });
  return (typeof result.body === 'object') ? result.body : JSON.parse(result.body);;
}

然后再新建函数getCacheToken()调用getAccessToken()获得access_token并存入云数据库中

async getCacheToken(){
    let collection = 'access_token';//数据库集合名称
    let gapTime = 300000; // 5 分钟
    cloud.init();
    let db = cloud.database();
    let result = await db.collection(collection).get();
    if (result.code) {
          return null;
    }
    // 数据库没有,获取
    if (!result.data.length) {
        let accessTokenBody = await this.getAccessToken();
        let act = accessTokenBody.access_token;
        let ein = accessTokenBody.expires_in  1000;
        await db.collection(collection).add({
            data: {
              _id: 1,
              accessToken: act,
              expiresIn: ein,
              createTime: Date.now()
          }
        });
        return act;
    }
    else {
          let data = result.data[0];
          let {
            _id,
            accessToken,
            expiresIn,
            createTime
          } = data;
          // 判断access_token是否有效
          if (Date.now() < createTime + expiresIn - gapTime) {
            return accessToken;
          }
         // 失效,重新获取
          else {
            let accessTokenBody = await this.getAccessToken();
            let act = accessTokenBody.access_token;
            let ein = accessTokenBody.expires_in  1000;
            await db.collection(collection).doc(_id).set({
                  _id: 1,
                  accessToken: act,
                  expiresIn: ein,
                  createTime: Date.now()
            });
            return accessTokenBody.access_token;
        }
    }
}

完整:云函数 getAccessToken 下新建 AccessToken.js

const cloud = require('wx-server-sdk')const request = require('request')class AccessToken {
    constructor({
        appid,
        secret  }) {
        this.appid = appid    this.secret = secret  }
    // 获取公众号access_token
    async getWechatAccessToken() {
        let token_url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' + this.appid + '&' + 'secret=' + this.secret;
        const rp = options =>
        new Promise((resolve, reject) => {
            request(options, (error, response, body) => {
                if (error) {
                    reject(error);
                }
                resolve(response);
            });
        });
        const result = await rp({
            url: token_url,
            method: 'GET'
        });
        return (typeof result.body === 'object') ? result.body : JSON.parse(result.body);;
    }

// 获取保存在数据库的公众号access_token

async getCachedWechatAccessToken() {
    let collection = 'wx-access-token'; //数据库集合名称
    let gapTime = 300000; // 5 分钟
    cloud.init();
    let db = cloud.database();
    let result = await db.collection(collection).get();
    if (result.code) {
        return null;
    }
    // 数据库没有,获取
    if (!result.data.length) {
        let accessTokenBody = await this.getAccessToken();
        let act = accessTokenBody.access_token;
        let ein = accessTokenBody.expires_in  1000;
        await db.collection(collection).add({
            data: {
                _id: 1,
                accessToken: act,
                expiresIn: ein,
                createTime: Date.now()
            }
        });
        return act;
    } else {
        let data = result.data[0];
        let {
            _id,
            accessToken,
            expiresIn,
            createTime      } = data;
        // 判断access_token是否有效
        if (Date.now() < createTime + expiresIn - gapTime) {
            return accessToken;
        }
        // 失效,重新获取
        else {
            let accessTokenBody = await this.getWechatAccessToken();
            let act = accessTokenBody.access_token;
            let ein = accessTokenBody.expires_in  1000;
            await db.collection(collection).doc(_id).set({
                _id: 1,
                accessToken: act,
                expiresIn: ein,
                createTime: Date.now()
            });
            return accessTokenBody.access_token;
        }
    }
}}
module.exports = AccessToken

在云函数入口文件中声明并传入微信公众号开发者id及secret_key即可,然后在小程序客户端调用云函数即可获取

// 云函数入口文件index.js

const cloud = require('wx-server-sdk');
const request = require('request');
const access_token = require('AccessToken');//引入AccessToken类
cloud.init()
let appid ='*';//微信公众号开发者id
let secret ='*';//微信公众号开发者secret_key
// 云函数入口函数
exports.main = async (event, context) => {
    let atn = new access_token({
        appid,
        secret
    });
    return atn.getCacheToken();
}

页面调用,编译调试

//可以在onLoad方法中 调试

onLoad: function (options) {
    wx.cloud.callFunction({
        // 云函数名称
        name: 'getAccessToken',
        success: function (res) {
            console.log("getAccessToken  result")
            console.log(res.result) 
        },
        fail: console.error    })
}

调试结果如下:

微信小程序云开发调用access_token调用微信公众号素材

特别要注意的就是这个过程中会出现异步的问题,导致获取的access_token为空,出现报错,第一次开发报错信息很乱不太懂,后面就习惯了!

评论专区