Introduction:

In order to facilitate small program applications to use wechat login mode for authorization and login, wechat small program provides an open interface for login authorization. At first glance, the document makes a lot of sense, but the implementation is really confusing, and I don’t know how to manage and maintain the login state. This article will teach you how to access and maintain wechat login state in the business hand in hand.

Access to the process

The flow chart in the official document here is clear enough, so let’s expand on it and supplement it.

First of all, when you see this picture, you will certainly notice that the small program for communication interaction is not only the small program front end and our own server, wechat third-party server is also involved, so wechat server in which to play what role? Let’s go through the process of login authentication.

1. Invoke wx.login to generate a code

The purpose of the WX.login () API is to generate a temporary login credential for the current user that is valid for only five minutes. Once we have this login credential, we can proceed to the next step: obtain the OpenID and session_key

wx.login({
    success: function(loginRes) {
        if (loginRes.code) {
            // example: 081LXytJ1Xq1Y40sg3uJ1FWntJ1LXyth}}});Copy the code

2. Obtain the OpenID and session_key

Let’s first introduce OpenID, children who have used the public number should be familiar with this logo, in the public platform, used to identify each user in the subscription number, service number, small program these three different applications of the unique identifier, that is to say, each user in each application openID is inconsistent, so in the small program, We can use OpenID to identify the uniqueness of a user.

So what does session_key do? With the user id, we need to allow the user to log in, so the session_key ensures the validity of the current user’s session operations. This session_key is distributed to us by the wechat server. In other words, we can use this identifier to indirectly maintain the login state of our miniprogram users, so where does this session_key come from? We need in your own server request WeChat provide third-party interface https://api.weixin.qq.com/sns/jscode2session, this interface need to take four parameters field:

parameter value
appid Appid of the applet
secret Small program secret
js_code The code issued by the previous call to WX.login
grant_type ‘authorization_code’

From these arguments, we can see that to request this interface, we must first call wx.login() to get the code of the user’s current session. So why do we request this interface on the server? In fact, for security reasons, if we call this interface through request on the front end, it is inevitable to expose the appID and secret of our small program to the outside, and also expose the session_key sent by the wechat server to “interested people”. This brings great risks to our business security. In addition to obtaining the session_key on the server, we need to note two things:

  • The session_key corresponds to the code distributed by wechat. One CODE can exchange only one Session_key. Each time wx.login() is called, a new code and the corresponding session_key will be issued. To ensure the user experience and the validity of login mode, developers need to know that wx.login() is called only when the user needs to login again.

  • Session_key is time-sensitive. It will expire even if wx.login is not called. The expiration time is positively correlated with how often the user uses the mini program, but the specific duration is not available to either the developer or the user

function getSessionKey (code, appid, appSecret) {
    var opt = {
        method: 'GET'.url: 'https://api.weixin.qq.com/sns/jscode2session'.params: {
            appid: appid,
            secret: appSecret,
            js_code: code,
            grant_type: 'authorization_code'}};return http(opt).then(function (response) {
        var data = response.data;
        if(! data.openid || ! data.session_key || data.errcode) {return {
                result: 2 -.errmsg: data.errmsg || 'Returned data field incomplete'}}else {
            return data
        }
    });
}
Copy the code

3. Generate 3 rd_session

As mentioned earlier, the session_Key is used to “indirectly” maintain the login state. The so-called “indirectly” means that we need to maintain the login state information of users by ourselves. For security reasons, if we directly use the session_key distributed by the wechat server as the login state of the business side, For example, the wX.getUserInfo () interface requires session_Key to decrypt the sensitive information of a wechat user.

Then if we generate our own login state identifier, we can use several common irreversible hash algorithms, such as MD5, SHA1, etc., to return the generated login state identifier (collectively called ‘skey’) to the front end, and maintain this login state identifier (generally stored in storage) in the front end. On the server side, we will store the generated skey in the data table corresponding to the user, and the front-end passes the skey to access the user’s information.

You can see here that we used the SHA1 algorithm to generate a skey:

const crypto = require('crypto');

return getSessionKey(code, appid, secret)
    .then(resData= > {
        // Select an encryption algorithm to generate your own login id
        const { session_key } = resData;
        const skey = encryptSha1(session_key);
    });
    
function encryptSha1(data) {
    return crypto.createHash('sha1').update(data, 'utf8').digest('hex')}Copy the code

4. checkSession

What if session_key expires when skey is stored in the front-end storage and is carried with each user data request? So we need to call the Wx.checkSession () API to verify that the current session_key has expired. The API does not need to pass any session_key parameters. Instead, wechat small program to adjust their own services to query the user’s last generated session_key expired. If the current session_key expires, ask the user to log in again, update the session_key, and store the latest skey in the user data table.

The checkSession step is usually placed in the logic of checking the logon state when the small program is started. Here is a flowchart of checking the logon state:

The following code is a simple process to verify the logon state:

let loginFlag = wx.getStorageSync('skey');
if (loginFlag) {
    // Check whether session_key is expired
    wx.checkSession({
        // session_key valid (not expired)
        success: function() {
            // Business logic processing
        },
    
        / / session_key expired
        fail: function() {
            // Session_key expires. Log in againdoLogin(); }});else {
    // If there is no skey, it is the first login
    doLogin();
}
Copy the code

5. Emoji storage

If you need to store the user’s wechat name in the data table, then confirm the encoding format of the data table and data columns. Because users’ wechat names may contain emoji ICONS, and the commonly used UTF8 encoding only supports 1-3 bytes, emoji ICONS are just 4 bytes encoding for storage.

There are two ways (using mysql as an example) :

1. Set the storage character set

Mysql5.5.3 supports utf8mb4 for databases, tables, and columns, so you can set the default character set encoding and server encoding format in /etc/my.cnf

// my.cnf

[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
[mysqld]
character-set-client-handshake = FALSE
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
Copy the code

After setting the default character set encoding and server character set encoding, perform the following steps to convert existing tables and fields:

  • Set the database character set toutf8mb4
ALTER DATABASE DATABASE name CHARACTER SET = UTf8MB4 COLLATE = UTF8MB4_unicode_CI;Copy the code
  • Set the data table character set toutf8mb4
ALTER TABLE ALTER TABLE TABLESPACE name CONVERT TO CHARACTER SET UTF8MB4 COLLATE UTF8MB4_unicode_CI;Copy the code
  • Set the data column field character set toutf8mb4
VARCHAR(n) CHARACTER SET UTF8MB4 COLLATE UTF8MB4_unicode_CI;Copy the code

Utf8mb4 uses collation to sort and compare stored characters. Utf8mb4 uses collation to sort and compare stored characters. Utf8mb4_unicode_ci and UTF8MB4_general_CI. Utf8mb4_unicode_ci is generally recommended because it is based on the standard Unicode Collation Algorithm(UCA) for sorting. Precise ordering is possible in a variety of languages. See What’s the difference between UTF8_general_CI and UTF8_unicode_CI for details

  1. Emoji characters are encoded into the library using Sequelize, and then decoded when used

Here is the sequelize configuration, refer to the Sequelize documentation

{
       dialect: 'mysql'.// Database type
       dialectOptions: {    
         charset: 'utf8mb4'.collate: "utf8mb4_unicode_ci"}},Copy the code

The last

In front of the micro channel small program how to connect to the micro channel login state identification of the detailed process, so how to obtain the user data in the small program and decrypt the user sensitive data, and ensure the integrity of user data, I will give you a detailed introduction in the next article.


“IVWEB Technology Weekly” shock online, pay attention to the public number: IVWEB community, weekly timing push quality articles.

  • Weekly articles collection: weekly
  • Team open source project: Feflow