Front end vue + background node to obtain basic information of wechat users + call wechat JS-SDK

1. Get the basic information of wechat users

2. vue access wechat JS SDK

Environmental Science:

Front end: vue2.0

Background: node.js

Official account: test number provided by WeChat

Take sharing to wechat and sharing to the circle of friends as examples.

After the wechat web page is connected to the wechat JS-SDK, the wechat web page will be presented in the following way after sharing with the wechat group and wechat friends:

If there is no access to JS-SDK, the rendering method is this:

There are obvious differences in appearance. In addition, JS connected to wechat_ The SDK can also easily call the functions provided by wechat to the third-party interface, such as taking photos, locating, obtaining network status, etc

Next, let's officially start practice~

Find the JS-SDK description document in the official wechat document

The link is as follows:

Overview | wechat open documents

The page is as follows:

After reading the document, we know that the process of accessing wechat JS-SDK is as follows:

Testing public official account preparation:

Fill in the server domain name in the JS interface security domain name module. If no domain name has been registered or the project is in the local development stage, it is recommended to use the temporary domain name generated by the intranet penetration tool to replace it (this method is recommended. See the previous document for the intranet penetration website and configuration).

Background work:

  1. According to the official account number AppID and APPSecret, get the accessToken. provided by WeChat server to WeChat third party web page.

// Get a new AccessToken from wechat server
function getAccessTokenFromWechatServer() {
    return new Promise(async (resolve, reject) => {
        try {
            const uri = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${CONFIG.appID}&secret=${CONFIG.appSecret}`;
            resolve(await getRequest(uri));
        } catch (err) {
            reject(err);
        }
    })
}

// Wechat JSAPI call example
app.get('/jsApi',async (req,res) => {
    const url = req.query.pageUrl;
    console.log(url);
    //Get accessToken -- valid for 2 hours
    const accessToken = await getAccessTokenFromWechatServer();
    console.log(accessToken);
    // Save the generated accessToken to the database
})

2. Access obtained in step 1_ Token to request JS from wechat server_ Ticket, which is used for subsequent generation of front-end call JS_ config parameter required for SDK

// Get new jsapi from wechat server_ ticket
function getJSAPITicketFromWechatServer() {
    return new Promise(async (resolve, reject) => {
        try {
            const AccessToken = webAccessToken;
            const uri = `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${AccessToken}&type=jsapi`;
            resolve(await getRequest(uri));
        } catch (err) {
            reject(err);
        }
    })
}

// Wechat JSAPI call example
app.get('/jsApi',async (req,res) => {
    // Get ticket -- valid for 2 hours
    const jsTicket = await util.getJSAPITicketFromWechatServer();
    console.log(jsTicket);
    // Save the obtained jsTicket to the database
})

3. The third step is to generate the wx related parameters required when the front end calls the wechat interface.

Relevant parameters include appId, timestamp, nonceStr and signature:

AppId is the appId. of the official account.

Timestamp is a timestamp, generated by Date.noew(), written as js

nonceStr is a random string that generates a signature. It is an example of an official website document. It should be an indefinite length string that is not composed of numbers, lowercase letters and uppercase letters.

Signature is a little complicated. Wechat officially provides a signature algorithm:

signature algorithm

The signature generation rules are as follows: the fields participating in the signature include noncestr (random string) and valid jsapi_ticket, timestamp, URL (the URL of the current web page, excluding # and its subsequent parts). After sorting all parameters to be signed according to the ASCII code of the field name from small to large (dictionary order), use the format of URL key value pairs (i.e. key1 = value1 & key2 = Value2...) to splice them into string string1. Note that all parameter names are lowercase characters. sha1 encryption is performed for string1. The field name and field value adopt the original value without URL escape.

Signature by jsapi_ticket, nonceStr, timestamp and url generation, assuming that the four parameter values are:

noncestr=Wm3WZYTPz0wzccnW 
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg 
timestamp=1414587457 
url=http://mp.weixin.qq.com?params=value

The specific steps of signing are as follows:

Step 1: after sorting all parameters to be signed according to the ASCII code of the field name from small to large (dictionary order), use the format of URL key value pair (i.e. key1 = value1 & key2 = Value2...) to splice them into string string1:

jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW&timestamp=1414587457&url=http://mp.weixin.qq.com?params=value

Step 2: sha1 sign string1 to get the signature:

0f9de62fce790f9a083d5c99e95740ceb90c27ed

The signature generation algorithm written in node.js is:

// Generate a random string with a length of 16
let getRandomWord = (randomFlag, min) => {
    let str = "";
    let range = min;
    let arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];

    for (let i = 0; i < range; i++) {
        let pos = Math.round(Math.random() * (arr.length - 1))
        str += arr[pos]
    }

    return str;
}

// The url is the full page address # before the front page
async function getConfig(url) {
    return new Promise(async (resolve, reject) => {
        try {
            // Get the jsapi in the database_ ticket
            const TICKET = jsTicket;
            // Current timestamp
            const timestamp = Date.now();
            // Random string
            const nonceStr = getRandomWord(false, 16);
            // Sort by dictionary
            const str = `jsapi_ticket=${TICKET}&noncestr=${nonceStr}&timestamp=${timestamp}&url=${url}`;
            // Obtain signature after sha1 encryption
            const signature = crypto.createHash('sha1').update(str, 'utf-8').digest('hex');
            resolve({
                timestamp,
                nonceStr,
                signature,
                appId: CONFIG.appID
            });
        } catch (e) {
            reject(e);
        }
    })
}

Finally, return the generated parameter config to the foreground

// Wechat JSAPI call example
app.get('/jsApi',async (req,res) => {
    const jsConfig = await getConfig(url);
    let result = {
        statusCode: '200',
        msg: 'Request succeeded',
        data:{
            'wxJDK':jsConfig
        }
    }
    res.send(JSON.stringify(result));
})

At this point, the tasks to be processed in the background part are completed. Start the background service and wait for the request from the foreground.

Next is the front part:

Take vue2.6.12 project as an example:

Step 1:

According to the official wechat document, we need to introduce the following Js files into the index.html file of the project:

<script src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>

To further improve service stability, when the above resources are inaccessible, they can be introduced instead

<script src="http://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>

Step 2:

It is recommended to separate the wechat JS SDK configuration file into a module to expose the interface for relevant pages:

Create a new utils folder in the src directory, and create a new wxApi.js file in this folder:

The contents of the document are:

//utils.js
const wxApi = {
  wxRegister(data, option) {
    console.log("hello");
    console.log(data)
    console.log(option)
    wx.config({
      debug: true, // Turn on debugging mode
      appId: data.appId, // Required, the only sign of official account.
      timestamp: data.timestamp, // Required, time stamp to generate signature
      nonceStr: data.nonceStr, // Required, generate random string of signature
      signature: data.signature, // Required, signature
      jsApiList: [
        "updateTimelineShareData", //The latest sharing circle of friends
        "updateAppMessageShareData", //Latest sharing friends
      ] // Required, list of JS interfaces to be used. See Appendix 2 in wechat document for the list of all JS interfaces
    });
    wx.ready(function() {
      // Data shared by wechat
      let shareData = {
        title: option.title, // Share title
        link: option.link, // Share links
        imgUrl: option.imgUrl, // Share Icon
        desc: option.desc, // Share description
        success: function() {
          console.log("hello")
          // Callback function executed after user successfully shares
          option.success();
        },
        fail: function() {
          console.log("failed")
          // Callback function executed after user cancels sharing
          option.error();
        },
        complete: function() {
          console.log("finish")
          // alert('end of call ')
        }
      };

      wx.updateTimelineShareData(shareData);
      wx.updateAppMessageShareData(shareData);

      wx.error(function(_res) {
        // If the verification of config information fails, the error function will be executed. For example, the verification fails due to the expiration of the signature. The specific error information can be viewed in the debug mode of config or in the returned res parameter. For SPA, the signature can be updated here.
      });
    });
  }
};
export default wxApi;

Step 3: import the configuration file in the component to be used, assuming it is called A.vue

<template>
  <div>
  ...
  </div>
</template>
<script>
import wxApi from "../../../utils/wxApi";

export default {
  name: "articleDetail",
  data() {
    return {
    ...
    }
  },
methods: {
    async shareArticle(option) {
      // First go to the background to get the jsConfig of wechat, and then trigger the sharing event
      let postData = {
        pageUrl: window.location.href.split('#')[0]
      }
      let url = JSON.parse(getUrl()).contextShare.wxConfig;
      const result = (await this.$http.get(url, {params: postData})).data.data.wxJDK;
      let wxConfig = {
        appId: result.appId,
        timestamp: result.timestamp,
        nonceStr: result.nonceStr,
        signature: result.signature
      }
      // shareMsg content customization
      let shareMsg = {
        title:'nice to meet you',
        desc:'It's a nice day today~',
        link:'Custom, link names need to be configured in official account. js Same domain name',
        imgUrl:'custom'
      }
      // Request from wechat to share the interface to wechat friends and wechat circle of friends
      await wxApi.wxRegister(wxConfig,shareMsg);
    }
  }
}
</script>

<style lang="less" scoped>
...
</style>

So far, the function of calling wechat JS SDK has been completed!

Tags: Javascript Front-end wechat

Posted on Tue, 09 Nov 2021 14:43:37 -0500 by Revlet