preface

Two days ago, I made an H5, which is mainly used for display on mobile terminals and can be forwarded and spread in wechat in a friendly way.

When H5 forwarded the card to friends after completion, it was found that the introduction and icon of the forwarding card were all wechat default style ICONS, which was very unfriendly. In addition, the product student strongly suggested that the content should be customized. As shown in the figure.

The time is tight and the task is heavy. We only have one day’s development time. The wechat information is checked and the code is followed by the document.

The body of the

Research found that there is a very interesting things: in fact, to do before thinking of this simple requirement, there should be a very mature community tutorial, however, surprised, found on a on a BBS are hang sheep head sell vinegar post, link guide is xyz company professional service enterprise custom WeChat forwarding card content… Employees are from XXX factory. (OMG turns out this is also a commercial market). In an effort to to

Oh, here’s the text (😏)


First, preparation

Starting from this demand, since we want to modify the content of wechat forwarding card, we just want to find a way to realize how to access the wechat SDK and make reasonable use of the original functions of wechat. How to access the wechat SDK, after a series of searches, the wechat web development JS-SDK documentation can achieve all the needs, of course, the document is only the first step, the pit is the biggest challenge.

The following preparations need to be made according to the document:

  1. First of all, we need an enterprise wechat public account (personal account is not available, why will be explained later).

  2. Set the security domain name of the JS interface

The important thing to note here is the content in the red box. The authentication code file needs to be placed in the DNS root directory that you configured (for front-end developers, just put the authentication file in the index.html equivalent of the front-end project).

  1. The introduction of WeChatsdkThe script

  2. Signature generation (according to the unique identifier of public number, timestamp of signature, random string of signature and other fields for processing and sha1 algorithm to generate signature)

  3. Verify the configuration by injecting SDK permission through the Config interface

  4. Call wechat SDK capabilities (mainly used here to share to friends, share to moments and other interfaces)

Those of you who are careful may have noticed that there is a step No.4 missing. (In fact, I realized in the implementation phase of the code, missing this core step, what is explained later)

Two, start the code

According to the operation process of wechat development manual to carry out the code.

Introduce the JS script of wechat SDK,

// index.html
<script src="http://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
Copy the code

The following is the preparation of some logic for generating signature and SDK permission verification.

Specific process:

  1. Get jsapi_ticket

Jsapi_ticket is a temporary ticket used by the public account to invoke the JS interface of wechat. The jsapi_ticket is valid for 7200 seconds and can be obtained using an access_token.

const axios = require('axios');

let [appid, appsecret] = ['your appid'.'your appsecret']; // Public account platform to obtain this information
/ / get access_token
const accessTokenUrl = 
`https://api.weixin.qq.com/cgi-bin/token?grant_type=The ${'client_credential'}&appid=${appid}&secret=${appsecret}`;
const r = await axios.get(accessTokenUrl);
const access_token = r.data;

/ / get jsapi_ticket
const ticketUrl =
	`https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${access_token}&type=jsapi`;
const res = await axios.get(ticketUrl);
let { errcode, ticket, expires_in } = res.data;
console.log('jsapi_ticket', ticket);
Copy the code
  1. To generate the signature
// Introduce sha1 encryption algorithm
const sha1 = require('sha1');

const LINK = 'xx.xx.com'; // Set the parameters of the JS interface security domain name above
const time = +new Date(a);// Time stamp of the signature
const noncestr = time + 's'; // A random string of signatures
const url = LINK;

const encodeStr = 
`jsapi_ticket=${ticket}&noncestr=${noncestr}&timestamp=${time}&url=${url}`;
// Generate a signature
const signature = sha1(encodeStr);

Copy the code
  1. Verify the configuration by injecting SDK permission through the Config interface
// WX SDK permission authentication configuration
wx.config({
	// If debug mode is enabled, the return value of all API calls will be displayed in the client alert
	debug: false.// Mandatory, the unique identifier of the public account
	appId: wxdata.appid, 
	// Mandatory to generate the timestamp of the signature
	timestamp: wxdata.timestamp, 
	// Mandatory to generate a random string of signatures
	nonceStr: wxdata.noncestr, 
	// Mandatory, signature, see Appendix 1
	signature: wxdata.signature, 
	// Mandatory, a list of JS interfaces to be used. See Appendix 2 for a list of all JS interfaces
	jsApiList: [
		"onMenuShareTimeline"."onMenuShareAppMessage"."updateAppMessageShareData"."updateTimelineShareData"]});// The SDK permission verification configuration is successfully callback
wx.ready(function() {
	console.log('wx.ready success');
})
// SDK permission verification configuration failed to be called back
wx.error(function(res) {
	console.log('wx.error', res);
});

Copy the code

The code is done, done!! yyds !!


After the test, I sent the test environment of the configured domain name. When I opened the web page, THERE was no console information, but several cross-domain warning messages were reported. Xx.xx.com could not directly access api.weixin.qq.com.

I thought I would be relieved when I finished, but the warning came out of the blue and told me that this was just the beginning.

After some reflection and review of the document, it is found that the process of signature authentication can not be simply completed in the front end, which will be very insecure, and the document also says: for security reasons, the developer must implement the signature logic in the server side.

Due to the need to test and verify the feasibility of this process in advance and whether the final implementation effect is up to standard, I had no choice but to install a Node server by myself and deploy it to the test environment (under normal circumstances, due to the limitation of server permissions, operation and maintenance students need to cooperate to complete it).

Therefore, the above code needs to be broken down into the front/back end code.

1. Front end

The url is [IP]:[port]/ API /wxconfig. The return value is {code: 200, data: {timestamp,noncestr, URL,signature, appID}}

Ok, the front and back end conventions are complete.

To clean up the front end of the code, change the logic to validate the WX permission and get the config parameter from node Server.

import axios from 'axios';

const wx_url = `//[ip]:[port]/api/wxconfig`;
const res = await axios.get(wx_url);
const { timestamp, noncestr, url, signature } = res.data;

// WX SDK permission authentication configuration
wx.config({
	debug: false.// Mandatory, the unique identifier of the public account
	appId: wxdata.appid, 
	// Mandatory to generate the timestamp of the signature
	timestamp: wxdata.timestamp, 
	// Mandatory to generate a random string of signatures
	nonceStr: wxdata.noncestr, 
	// Mandatory, signature, see Appendix 1
	signature: wxdata.signature, 
	// Mandatory, a list of JS interfaces to be used. See Appendix 2 for a list of all JS interfaces
	jsApiList: [
		"onMenuShareTimeline"."onMenuShareAppMessage"."updateAppMessageShareData"."updateTimelineShareData".'hideMenuItems']});// The SDK permission verification configuration is successfully callback
wx.ready(function() {
	console.log('wx.ready success');

	// Wechat moments share function
	wx.updateTimelineShareData({
		// Configure user-defined parameters
	});
	wx.onMenuShareTimeline({
		// Configure user-defined parameters
	});
	// Share with friends
	wx.updateAppMessageShareData({
		// Configure user-defined parameters
	});
	wx.onMenuShareAppMessage({
		// Configure user-defined parameters
	});
})
// SDK permission verification configuration failed to be called back
wx.error(function(res) {
	console.log('wx.error', res);
});

Copy the code

2. On the server

Write node server code. (The figure here is convenient to use the Express framework directly)

const express = require('express');
const netpro = require('netpro'); // Used to get address
const axios = require('axios'); 
const sha1 = require('sha1'); 

const app = express(); 

app.get('/api/wxconfig'.function(req, res) {
	
	res.set('Access-Control-Allow-Origin'.The '*');

	getWXConfig().then(data= > {
		res.send({code:200, data})
	})
})

async function getWXConfig() {
	let [appid, appsecret] = ['your appid'.'your appsecret']; // Public account platform to obtain this information
	/ / get access_token
	const accessTokenUrl = 
  `https://api.weixin.qq.com/cgi-bin/token?grant_type=The ${'client_credential'}&appid=${appid}&secret=${appsecret}`;
	const r = await axios.get(accessTokenUrl);
	const access_token = r.data;

	/ / get jsapi_ticket
	const ticketUrl =
		`https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${access_token}&type=jsapi`;
	const res = await axios.get(ticketUrl);
	let { errcode, ticket, expires_in } = res.data;
	console.log('jsapi_ticket', ticket);

	const LINK = 'xx.xx.com'; 
  // You can also define this parameter in the front end to pass
	const timestamp = +new Date(a);// Time stamp of the signature
	const noncestr = time + 's'; // A random string of signatures
	const url = LINK;

	const encodeStr = 
  `jsapi_ticket=${ticket}&noncestr=${noncestr}&timestamp=${timestamp}&url=${url}`;
	// Generate a signature
	const signature = sha1(encodeStr);

	return {
		appid,
		signature,
		noncestr,
		timestamp,
		url,
	}
}

const address = netpro.address();

app.listen(PORT);

console.log('Node-server service started, address:${address}:${PORT}`);

Copy the code

The node server is installed on the test server

However, after testing, it was found that the Node server could not pass the HTTP request to access the wechat API, which probably means that the IP is not in the whitelist.

On second thought, the impression seems to have seen this parameter configuration item in the wechat public platform, so after finding the configuration of the white list. As shown in the figure.

In fact, this step to configure the server IP whitelist is the above mentioned step No.4.

At this point, all the tests have passed, sharing cards can also be customized content and images, finally a relief.

Finally, let the server students to change the node part of the logic into Java and distributed to the production environment, add IP whitelist also verified through, because here is mainly based on the front-end development of the introduction, some details of the server side special processing is not discussed here, specific can be the public account background to consult me.

Other:

  • There is also a pit here, the wechat sharing function needs to be authenticated by wechat to have the permission to use, but personal accounts are not allowed to be authenticated, enterprise accounts can only apply, authentication needs to pay an annual fee, authentication cycle of 1-3 working days.

  • For the sake of service stability and work focus, online environment is not recommended to develop their own front-end server, simple verification test can play.

  • The above code is not available in production, boundary handling/exception handling/time-out handling is not included.

Third, the final effect

<.>

conclusion

After a series of validation, failure, validation, the requirement is finally complete.

As a developer, this kind of process should be a regular one, and enjoying the process may be more fun than the result.


One of the screenshots above seemed like a joke, but it made me rethink the real value. .

Take your stuff and give it to someone who needs it. It may seem simple to you, but it has a lot of value to someone who needs it. Just as our lives are controlled by an invisible hand.


Follow wX official account:Front end little rookie 001, regularly share quality content ~