WeChat Open Platform Development (2)

When I created a third-party application and passed the review, I found that I didn’t know what to do. That’s exactly what I felt at the time. I felt that the documents of the WeChat Open Platform were not as clear as the WeChat public platform, and the WeChat Open Platform still quoted WeChat in many places. The link to the public platform, but what if the developer has not developed the WeChat public platform? Complaints are grievances, but things still need to be done, so I had to resort to the Internet, and fortunately found a series of blogs (explained in the first blog of this series), let me understand step by step, and finally realized the function.

Framework implementation

Because I am more proficient in using Java, the framework also uses SpringMVC+Spring. The demo does not involve the database, so the database and orm framework are not used.

If you have seen my WeChat official account webpage authorization code optimization process , you may know that I used it to create a demo project on the code cloud . The address of the demo project is https://gitee.com/valuetodays/open-wx-demo , and as before, each function point will be marked with a tag after it is completed.

The framework has been built, and the project adopts the general MVC framework, but since the demo project does not need to connect to the database, there are only two layers of controller and service, which will be explained below.

  • The name of the basic package is com.billy.demo.open. I feel that this name is inappropriate. Let’s use it together ^_^.
  • Store some constant classes under the constants package
  • All control layer classes are stored under the controller package. Currently, there is only one class, AuthController, which is used to receive and process component_verify_ticket sent by WeChat.
  • service is the class corresponding to the controller
  • task is a task scheduling class. To dynamically process component_access_token, you can also use redis instead of timer. The demo project is mainly to use less dependencies and configuration
  • The entity package stores some POJOs, which encapsulate the parameters received from WeChat or sent to WeChat
  • Util is a tool class used in the system, and the wx package under the util package is obtained from WeChat.
  • RequestParameterInterceptor, because WeChat sends all interface operations, so we added an interceptor that prints parameters to print the parameters of each interface, which is more convenient for debugging.

In addition, it should be emphasized that the code must be more LOG, more LOG, more LOG! Especially in the case where one change has to be published on the Alibaba Cloud server (it is more convenient to use peanut shells to debug, ^_^), during development I had to re-deploy it on Alibaba Cloud because I didn’t have to type LOG, and also You have to wait a few more minutes for WeChat's component_verify_ticket to be pushed (just at the beginning).

receive component_verify_ticket

Coding work is about to begin.

After the third-party application is approved, WeChat will send component_verify_ticket to the "authorized event receiving URL" every 10 minutes, which is an important parameter to obtain component_access_token. In order to receive this parameter, we will configure our authorization event receiving URL on the WeChat open platform. The configuration in src/main/filters/filter-dev-env.properties in this project is a little bit explained

APP_NAME=open-wx-demo
LOG_HOME=c:/tmp/logs/${APP_NAME}
appId=开放平台的appId
_secret=开放平台的appsecret
_encoding_aes_key=开放平台对应的aes_key
base_url=http://k16048m998.imwork.net/open-wx-demo

Among them, APP_NAME is the file name of the logback print log, that is, the project name, LOG_HOME is the storage directory of the log file; _appId, _secret, _encoding_aes_key are the appid, appsecret and message encryption and decryption key of the third-party platform, one of which should be noted is the message verification Token is written in src/main/resources/server.properties

At present, there is an AuthController class, a WxVerifyMsg, a bunch of utils, and a RequestParameterInterceptor in the project, and then explain them in turn.

  • AuthController, which receives WeChat authorization and de-authorization, authorization update messages, and is also used to receive component_verify_ticket, we are currently in order to obtain this value.
  • WxVerifyMsg, anyone who has been engaged in the development of WeChat public account knows that the data sent to you by WeChat has two parts, one part is sent in the form of key-value, and the other part is obtained from request.getInputStream(). Receive directly (of course, this is what SpringMVC provides).
  • util, to decrypt and encrypt the data sent by WeChat, and HttpClientUitl to send http/https requests.
  • RequestParameterInterceptor, only used for debugging, prints out the key-value parameters in the request, excluding the data in equest.getInputStream().

After the project runs, you can see the normal operation. For details, see Code Execution. Let's analyze the interface parameters. At the tenth minute, WeChat sent a request with the following data:

signature=edd055c66bc3255bf5e91f3ff32f18cf30b03c14
timestamp=1521524413
nonce=474592478	encrypt_type=aes
msg_signature=715514b4e74a4ec72ce7f79650442f015b2321a7

and

<xml>
    <AppId><![CDATA[wx95bab1ed8125031a]]></AppId>
    <Encrypt><![CDATA[B5f1x5Df41ijdYYrkGhAc9U2F1Ts3Ifk/otmXgY0w7OziphEzQNwkElI6+NDX7Nb3fe4Ef8b1JbgIThNmBwIEaES/wksGdxI7qU882p++29K0Z8aIBnBtHfVsDmqTbqvzRZgm2g3AcEY6w9f+241x6WsFdb4TuMqGPNbvYyfZBFM8gypAX7DqMkGXV5WaPJBkT9dxCWMh9g/n8K1oM1iDyk0rLq0NWIghh83rbVEvA+iDzSjy7NLB0UCKzO8xmav6mJ6DpmmRv0ilQVlKU49vyNldKLBSEDELb3piQb9uAdegRlK+TTA2fosPpBnNjY33xu0ueoqzYhlXaM+3LKhdM89jWTziXM4ollxV2r9MXDtVwIY9BCKIo6+sAECYIHdqH4rWDNX0jWmVBg5CK8ALezzv0+t18kM0p2QCZsyo5PLHPquqxIsIouX/wSNmwY6Mrr25iTZbX3uEj6CZsJzug==]]></Encrypt>
</xml>

The first part of the data is in the form of key-value, and the second part of the data is obtained from request.getInputStream() or encrypted. Use the decryption method provided by WeChat to decrypt into plaintext. The decrypted plaintext here is as follows (I have processed the value of AppId ^_^)

<xml><AppId><![CDATA[aaaaaaaaaaaaaaaaaaa]]></AppId>
<CreateTime>1521524413</CreateTime>
<InfoType><![CDATA[component_verify_ticket]]></InfoType>
<ComponentVerifyTicket><![CDATA[ticket@@@zJSa-304dQiQinvAvwWPNz6QpN5c7ZI9b1F8Fla4E51m9EIvZLk5TAHtZravdU2e-eXmCTJPqTNVRoaoae-GRA]]></ComponentVerifyTicket>
</xml>

You can see that there are two important parameters in the plaintext, the first is InfoType and the second is ComponentVerifyTicket. Be sure to judge that the InfoType is component_verify_ticket before getting ComponentVerifyTicket, otherwise don't get the value of ComponentVerifyTicket directly. I have encountered this problem as follows

    if (StringUtils.isNotEmpty(infoType)) {
        if (OpenConstants.INFOTYPE_COMPONENT_VERIFY_TICKET.equals(infoType)) {
            componentVerifyTicket = xmlMap.get("componentVerifyTicket");
            LOG.debug("componentVerifyTicket was flushed into redis.");
        }
    }

It was written for the first time

    componentVerifyTicket = xmlMap.get("componentVerifyTicket");
    LOG.debug("componentVerifyTicket was flushed into redis.");

Because both authorization and de-authorization will send data to this interface, the values ​​of InfoType that I know may be unauthorized, authorized, and component_verify_ticket. No list of all values ​​of InfoType has been found on the official website.

If nothing else, the program can correctly print out the value of component_verify_ticket. It should be noted that the developer should save the value (such as in Redis), in this example, it is stored in a variable, but after restarting, it has to wait for the next push from WeChat.

possible problems

InvalidKeyException: Illegal key size

If this problem occurs, please understand jce by yourself, and install the jce file. Note that it should match your jdk or jre.

Unsuccessful decryption of WeChat ciphertext

The download location of the encryption and decryption classes and demo provided by WeChat is here . If you cannot download it, please visit https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419318479&token=&lang =zh_CNSearch for "click to download" on the page.

Note that there is a problem with line 45 in the XMLParse class (big pit)

NodeList nodelist2 = root.getElementsByTagName("ToUserName");

If you look closely at the ciphertext sent by WeChat above, you will find that there are two contacts, Encrypt and AppId, under the xml contact, resulting in unsuccessful decryption. The solution is to change the above sentence to

NodeList nodelist2 = root.getElementsByTagName(root.getChildNodes().item(1).getNodeName());

That's it, the sample code has been modified. By the way, the above ToUserName actually handles the messages of the WeChat public account, so after changing it, the decryption function of the public account and the open platform can be processed at the same time.

The server cannot receive WeChat pushes every 10 minutes

If you use nginx at this time, check the nginx log. The problem I have here is the problem of https and http. It is normal to enter the address directly into the browser to access, but the request from WeChat cannot be received.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324454146&siteId=291194637