Using Temporary Two-Dimensional Code to Realize Wechat Scanning Login Function on Computer Browser-EasyWeChat Edition

Posted by Dane on Tue, 25 Jun 2019 20:08:45 +0200

> This method was initially used in the absence of "Wechat Open Platform", but now many websites are using it. In short, it generates a temporary two-dimensional code and puts it on the server. Then it scans the two-dimensional code and passes the value to the server for comparison, so as to realize landing, which is similar to the idea of mobile dynamic code landing.

Process description

Let's start with the steps we need to take:

  • Users access the Weichat landing page and the program generates a temporary two-dimensional code.
  • Users use Wechat to scan the newly generated two-dimensional code.
  • After scanning the code, wechat sends the content of the two-dimensional code to the website program.
  • Every N seconds, the client compares the second-dimensional code content of the first step with the two-dimensional code content that the website receives from Wechat. If it finds it, the login will be successful.

Dead work

Because the public account communication interface is needed for temporary two-dimensional code generation and code sweeping operation, we configure it first.( Wechat related pages ) First, create a new controller file named WxController.php under @app/controllers/, and define an action index to handle the interaction with Wechat, as follows:

namespace app\controllers;

use Yii;
use yii\web\Controller;
use EasyWeChat\Foundation\Application;// Introducing EasyWeChat

class WxController extends Controller {

    /**
     * Communication Processing Interface between Server and Wechat
     * @author abei<abei@nai8.me>
     */
    public function actionIndex(){
        /*
         * 'WECHAT'=>[
         *      'appId'=>'xxx',
         *      'appSecret'=>'xxxxx',
         *      'token'=>'nai8_me'
         * ]
         */
        $options = Yii::$app->params['WECHAT'];
        $app = new Application($options);

        $response = $app->server->serve();
        $response->send();
    }
}

According to Wechat documents, first we need to verify through the server.

$response = $app->server->serve();
$response->send();

This code is for processing and tweeting responses. We fill in the url and token of action on the test platform.

When the configuration validation is passed, we will deal with the various requests sent by the Wechat server, such as a text, such as a two-dimensional code scan, such as a geographical location, etc. Documents about EasyWechat interacting with the Wechat server can be viewed at the following address.

> https://easywechat.org/zh-cn/docs/tutorial.html

> https://easywechat.org/zh-cn/docs/server.html

Next, we will deal with the request sent by Wechat. In this document, we will deal with the receiving events after scanning the two-dimensional code. Of course, according to whether the current Wechat pays attention to the public number, the return of the scanned two-dimensional code is different. Because of the length, we only talk about the situation after paying attention.

The code after adding the function is as follows

namespace app\controllers;

use Yii;
use yii\web\Controller;
use EasyWeChat\Foundation\Application;// Introducing EasyWeChat

class WxController extends Controller {

    public $wxApp;

    /**
     * Communication Processing Interface between Server and Wechat
     * @author abei<abei@nai8.me>
     */
    public function actionIndex(){
        $options = Yii::$app->params['WECHAT'];
        $app = new Application($options);

        $server = $app->server;
        $this->wxApp = $app;

        $server->setMessageHandler(function ($message) {
            switch ($message->MsgType) {
                case 'event':// SCAN & subscribe
                    return $this->doEvent($message);
                    break;
            }
        });

        $response = $server->serve();
        $response->send();
    }

    /**
     * Handling events
     * @param $message
     * @author abei<abei@nai8.me>
     */
    protected function doEvent($message){
        switch ($message->Event) {
            case 'SCAN':
                return $this->doScan($message);
                break;
        }
    }

    /**
     * Handling specific scan events
     * @param $message
     * @author abei<abei@nai8.me>
     */
    protected function doScan($message){
        $key = $message->EventKey;
        $openId = $message->FromUserName;
        return $openId;
    }
}

To prevent the function from being too long, we split it into several small methods and add a variable called $wxApp to represent the interaction, concatenating each function.

We're here for the time being. Let's talk about it later.

Generating Temporary Two-Dimensional Codes

Now we use EasyWeChat to generate a temporary two-dimensional code, so define a function called actionQrcode.

namespace app\controllers;

use Yii;
use yii\web\Controller;
use EasyWeChat\Foundation\Application;// Introducing EasyWeChat

class WxController extends Controller {
    public $wxApp;

    ...

    public $enableCsrfValidation = false;

    /**
     * Generate a temporary two-dimensional code
     * @author abei<abei@nai8.me>
     */
    public function actionQrcode(){
        $options = Yii::$app->params['WECHAT'];
        $app = new Application($options);
        $qrcode = $app->qrcode;

        $rand = mt_rand(100000,999999);
        $result = $qrcode->temporary($rand, 6 * 24 * 3600);
        $ticket = $result->ticket;// Or $result['ticket']
        $url = $qrcode->url($ticket);

        return $this->render('qrcode',[
            'url'=>$url,
            'rand'=>$rand
        ]);
    }
}

The actionQrcode method places a random six-digit number in a temporary two-dimensional code. Here are two points to illustrate

  • The $url is the two-dimensional code picture address, which can be received directly in the view with the img tag.
  • Except that the Wechat server is validated as a GET request, all other events are POST requests, but yii2 defaults to crsf validation for POST submissions, so in order to effectively receive the push information from the Wechat server, we need to turn off crsf validation.
public $enableCsrfValidation = false; // I'm just going to turn off crsf validation droplets

So we generate a two-dimensional code with a value of $rand. There are many ways to complete the login. I use the browser request method here. In the action Qrcode view, I fill in the following code

<img src="<?= $url;?>" alt="">
<script>
    //todo makes a request to the program every N seconds and asks if a table called wx_qrcode has a record of $rand. If so, php completes the login and the browser jumps to pages such as the personal center.
</script>

So what follows is how the table called wx_qrcode is designed and how it records the problems that arise.

Important wx_qrcode tables

If you look at the Wechat document, you must know that when we use Wechat to scan temporary two-dimensional codes, Wechat not only tells us the random number of $rand represented by the two-dimensional codes of the server, but also has an identification called $openId, which represents the unique identity of the swept-code Wechat. So we designed the wx_qrcode table, which contains open_id and rand.

The idea is this.

  • After scanning the code, the program receives open_id and rand random codes transmitted by Wechat to initialize members and store the record in the wx_qrcode table.
  • The program receives the browser's request and queries wx_qrcode according to rand random code in the request. If it finds the record, it finds the open_id, and finds the member. Then it uses Yii:$app - > User - > login () method for login authorization, then deletes the record and returns it to the browser successfully. Otherwise, the return fails, and continues to let the browser inquire after N seconds.

That is to say, we need to modify the Wechat Scan Processing Program in the first step to do simple processing.

namespace app\controllers;

use Yii;
use yii\web\Controller;
use EasyWeChat\Foundation\Application;// Introducing EasyWeChat

class WxController extends Controller {

    public $wxApp;

    public $enableCsrfValidation = false;

    ...

    /**
     * Handling specific scan events
     * @param $message
     * @author abei<abei@nai8.me>
     */
    protected function doScan($message){
        $key = $message->EventKey;
        $openId = $message->FromUserName;

        $user = User::find()->where(['open_id'=>$openId])->one();
        if($user == false){
            //New members of todo
        }

        $wxQrcode = new WxQrcode();
        $wxQrcode->open_id = $openId;
        $wxQrcode->rand = $key;
        $wxQrcode->save();
    }
}

This is just a way of thinking, brothers according to their own system needs to improve the logic of this block, anyway, the scan reception, we need to fill in the wx_qrcode record, let the browser to ask.

ok, let me talk about how PHP handles the logic of browser consulting.

    public function actionAsk(){
        $rand = Yii::$app->request->get('key');
        $check = WxQrcode::find()->where(['rand'=>$rand])->one();
        if($check){
            $user = User::find()->where(['open_id'=>$check->open_id)->one();
            Yii::$app->user->login($user);

            $check->delete();

            return Json::encode(['done'=>true]);
        }else{
            //todo doesn't do anything, let the browser continue to ask.
        }
    }

To sum up

There are many kinds of scanned landing, such as no looping of views after generating two-dimensional codes, but sending micro-messages in the form of dynamic codes and template messages, and adding dynamic codes to the page to verify the landing, just like brothers'micro-messages landing.

There are many methods, the core of which is to use the content of two-dimensional code to transfer between PC and Wechat.

Topics: QRCode PHP Mobile JSON