Swoole implements WeChat code scanning login function

小云云
Release: 2023-03-19 14:36:01
Original
2193 people have browsed it

Scan QR code login method is increasingly used by current applications. Because there is no need to remember the password, as long as you have a WeChat ID, you can log in quickly and easily. This is based on the temporary QR code with parameters on the WeChat public platform, and is combined with Swoole's WebSocket service to achieve scan-code login. This article mainly shares with you Swoole to implement the WeChat code scanning login function, hoping to help everyone.

With the popularity of WeChat, the scanning code login method is increasingly used by current applications. Because you don’t have to remember the password, you can log in quickly and easily as long as you have a WeChat ID. WeChat’s open platform natively supports the function of scanning QR code to log in, but most people still use the public platform, so scanning QR code to log in can only be implemented by themselves. This is based on the WeChat public platform's temporary QR code with parameters, and combines it with Swoole's WebSocket service to implement scan-code login. The general process is as follows:

  1. The client opens the login interface and connects to the WebSocket service

  2. The WebScoket service generates a QR code with parameters and returns it to the customer End

  3. The user scans the displayed QR code with parameters

  4. The WeChat server calls back the scan event and notifies the developer server

  5. The developer server notifies the WebSocket service

  6. The WebSocket service notifies the client of successful login

Connects to the WebSocket service

After installing Swoole, we need to use the WebSocket service. Creating a new WebSocket service is very simple:

$server = new swoole_websocket_server("0.0.0.0", 1099);
$server->on('open', function (swoole_websocket_server $server, $request) use ($config){
  echo "server: handshake success with fd{$request->fd}\n";
});
$server->on('message', function (swoole_websocket_server $server, $frame) {
});
Copy after login

The message callback here is actually not useful, because the server sends messages, but one must be set. If the set port number is lower than 1024, you must have root permissions. Remember to open the port in the firewall on the server.

Generate QR code with parameters

After the WebSocket service successfully connects to the client, it needs to generate a WeChat QR code with parameters and return it to the client for display:

$server->on('open', function (swoole_websocket_server $server, $request) use ($config){
  $app = Factory::officialAccount($config['wechat']);
  $result = $app->qrcode->temporary($request->fd, 120);
  $url = $app->qrcode->url($result['ticket']);
  $server->push($request->fd, json_encode([
    'message_type'  => 'qrcode_url',
    'url'    => $url
  ]));
});
Copy after login

In the open callback, we generate a temporary QR code. The scene value of the QR code is the file descriptor of the client connection, so as to ensure the uniqueness of each client. The validity time is set to 120 seconds. , to prevent one QR code from being scanned and used multiple times. When the message is pushed to the client, json is required to facilitate client processing. The client code is also very simple:

const socket = new WebSocket('ws://127.0.0.1:1099');
  socket.addEventListener('message', function (event) {
    var data = JSON.parse(event.data);
    if (data.message_type == 'qrcode_url'){
      $('#qrcode').attr('src', data.url);
    }
  });
Copy after login

Callback scan code event

After the QR code is displayed on the client, the user needs to be prompted to scan the code. When a user scans a temporary QR code, WeChat will trigger a corresponding callback event, and we need to handle the user's code scanning behavior in the callback event. Among them, we need to use some parameters passed by WeChat:

FromUserName  发送方帐号(一个OpenID)
MsgType      消息类型,event
Event      事件类型,subscribe
EventKey    事件 KEY 值,qrscene_为前缀,后面为二维码的参数值
Copy after login

One thing to note here: the EventKey pushed by scanning the QR code that has been followed by WeChat does not have the qrscene_ prefix. It can only be found by scanning the QR code and then following it.

After receiving the WeChat callback, we first need to do different processing according to different event types:

if ($message['MsgType'] == 'event'){
  if ($message['Event'] == 'subscribe'){ //关注
    return $this->subscribe($message);
  }
  if ($message['Event'] == 'unsubscribe') { //取消关注
    return $this->unsubscribe($message);
  }
  if ($message['Event'] == 'SCAN'){  //已关注扫码
    return $this->scan($message);
  }
}else{
  return "您好!欢迎使用 SwooleWechat 扫描登录";
}
Copy after login

Here we only explain the business logic of one event of concern, and the others are coded by ourselves as needed:

public function subscribe($message){
  $eventKey = intval(str_replace('qrscene_', '', $message['EventKey']));
  $openId = $message['FromUserName'];
  $user = $this->app->user->get($openId);
  $this->notify(json_encode([
    'type' => 'scan',
    'fd'  => $eventKey,
    'nickname' => $user['nickname']
  ]));
  $count = $this->count($openId);
  $msgTemp = "%s,登录成功!\n这是你第%s次登录,玩的开心!";
  return sprintf($msgTemp, $user['nickname'], $count);
}
Copy after login

The EventKey here is actually the client file descriptor that connects to WebSocket, obtains the OPEN_ID of the user who scans the QR code, obtains user information based on the user's OPEN_ID, notifies the WebSocket service, and responds to WeChat with a text message.

One of the more troublesome points here is how to notify the WebSocket service. We know that the code for processing WeChat callbacks is not on the WebSocket service. So how do different servers communicate? There are two official solutions given by Swoole:

  1. Listen to an additional UDP port

  2. Use swoole_client as a client to access the Server

Here we choose the second option. Swoole 1.8 version supports one Server to listen to multiple ports. We add a new TCP port to the WebSocket service:

$tcp_server = $server->addListener('0.0.0.0', 9999, SWOOLE_SOCK_TCP);
$tcp_server->set([]);
$tcp_server->on('receive', function ($serv, $fd, $threadId, $data) {
  
});
Copy after login

The main server is WebSocket or Http protocol. The newly monitored TCP port will inherit the protocol settings of the main Server by default. The set method must be called separately to set the new protocol to enable the new protocol.

Then we can scan the QR code to call back Notify the WebSocket service in the process:

public function notify($message){
  $client = new swoole_client(SWOOLE_SOCK_TCP);
  if (!$client->connect('127.0.0.1', $this->config['notify_port'], -1)) {
    return "connect failed. Error: {$client->errCode}\n";
  }
  $ret = $client->send($message);
}
Copy after login

Notify of successful login

After the WebSocket service receives the notification of successful login, it can process the user information as needed, and then pass the user information to The client's browser displays the results. Do you remember the TCP port we just listened to? It can be processed in the receive event:

$tcp_server->on('receive', function ($serv, $fd, $threadId, $data) {
  $data = json_decode($data, true);
  if ($data['type'] == 'scan'){
    $serv->push($data['fd'], json_encode([
      'message_type'  => 'scan_success',
      'user' => $data['nickname']
    ]));
  }
  $serv->close($fd);
});
Copy after login

Last login interface:


Summary

The whole process is not difficult , the two main difficulties are the communication between QR code scanning users and different servers corresponding to connected users. Our solution is to use the connected file descriptor as a temporary QR code scene value (Redis can also be used to store the mapping relationship here) ), listen on the new TCP port to receive notification messages. You can visit http://wechat.sunnyshift.com/index.php to try it out, remember to open it on your computer.

Related recommendations:

How to implement custom WeChat code scanning login style

The idea and code of php to implement WeChat code scanning login

Detailed explanation of PC-side WeChat scan code registration and login example code

The above is the detailed content of Swoole implements WeChat code scanning login function. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template