uni-app with PHP for single user login

Keywords: Mobile socket SDK Android

Single user login, that is, in an application, only one user can login online, one user can login and be immediately offline on other devices. After confirmation, the login loading on the device is cleared and the login interface is returned.

uni-app is currently able to package Android, IOS, WeChat, PayPal and H5 with only one set of code by using the vue.js framework. It is easy to debug and package in the cloud by using the HBuilder tool. For Apple certificates, CW.PUB is recommended, https://cw.pub/index/document/index.The jailbreak pack with HBuilder can be installed on a normal Apple mobile phone by signing it on that website, but there are other methods on the Internet that are not listed here.

In general, APP single-user logins use third-party messaging push platforms, although uni-app can also dock with other push platforms such as allies and aurora.However, due to time, process time such as docking platform auditing is not allowed.Instant chats were previously done using gatewayworkman and websockets, so single-user logins are also implemented using websockets.

 

uni-app socket single user login example

1. The uni-app front end sends the unique identity of the current device when it initializes the socke, and then receives a message of type Forced Exit in real time. This is a simple example.

//Initialization
socket.on('init', () => { //Connection Initialization
	socket.send({
		type: 'login',
		token: uni.getStorageSync('access_token'),
		device_no: plus.device.uuid,			//Unique number of mobile device
	});
}).on('quit_push',(res)=> {
	if(res) {
		uni.showModal({
			title: 'Exit Notification',
			content: 'Your account is logged on to another device!',
			showCancel: true,
			cancelText: 'cancel',
			confirmText: 'Determine',
			success: res => {
				if(res.confirm) {
					uni.clearStorageSync()
					store.commit('chat/clear')
					uni.reLaunch({
						url:"../../pages/login/index"
					})
				}else if(res.cancel) {
					uni.clearStorageSync()
					store.commit('chat/clear')
					uni.reLaunch({
						url:"../../pages/login/index"
					})
				}
			}
		});
	}
});

 

2. The backend receives the Device Unique Identification parameter and first looks for the existence of the cache. There is no clientid that records the device identity and socket.

 

3. The logon interface receives device identities, caches or library fetches the identities records to determine whether they are consistent with the currently received device identities, and inconsistencies send messages based on the clientid in the cache.

$is_online = Db::name('UserLoginClient')->where('user_id',$user['id'])->order('id desc')->find();
if(isset($device_no) && $device_no && $is_online['device_no'] != $device_no && !empty($is_online['device_no'])) { 
		Tools::sendToClient($is_online['client_id'],json_encode([
																								'type' => 'quit_push',
																								'data' => 'ip',
																								'message' => 'Force offline'
																							]));
			}

 

4. Tool class sendToClient method section

public static function sendToClient($client_id, $message)
    {
        Gateway::sendToClient($client_id, $message);
    }

 

Push Single User Logon Example

1. Firstly, the allies, including front-end and back-end, have been added SDK s and used their methods.

 

2. Message pushing has a unique value of "token", which is simply "pushtoken". It is generated by the client and can identify a unique device.

 

3. When the backend logs on, it receives a pushtoken, and likewise determines if the pushtoken exists, and if it does not exist, it is stored with the user ID as the key.

 

4. If there is any consistency with the cache, consistency lengthens the cache time, and inconsistency pushes a message to the old pushtoken (in the cache) and caches the new pushtoken.

if (self::$headToken && Cache::has(self::$prefix . self::$userId)) {
            if (self::$headToken == Cache::get(self::$prefix . self::$userId)) {
                Cache::set(self::$prefix . self::$userId, self::$headToken, self::$timeOut);
            } else {        // Instead of a mobile phone, the client resends the pushtoken to the server, which compares with the cached pushtoken. Instead, it pushes one to the original pushtoken phone and caches the new token again.
                // modify by wensen on 20180816
                // $addr = getCity();
                $addr = getMobCity();
                $ip = request()->ip();
                
                if ($addr) {
                    $addr['province'] = empty($addr['province']) ? '' : $addr['province'];
                    $addr['city'] = empty($addr['city']) ? '' : $addr['city'];

                    // $address = "\t" . $addr['country'] . "-" . $addr['region'] . "-" . $addr['city'] . " (IP:" . $ip . ")\t";
                    $address = "\t" . $addr['country'] . "-" . $addr['province'] . "-" . $addr['city'] . " (IP:" . $ip . ")\t";
                } else {
                    $address = "IP:" . $ip . "";
                }

                $OldToken = Cache::get(self::$prefix . self::$userId);

                if (strlen($OldToken) == 64) {
                    $content = array(
                        'title' => 'APP Emergency Notification',
                        'body' => 'Your account number is in:' . date('Y-m-d H:i:s') . 'stay' . $address . 'Log on at,If you do not sign in for yourself,Please change your password now!',
                        'pull_service' => 'login'
                    );
                    \umeng\Push::send($OldToken, 'unicast', $content, 'message', true);
                } elseif (strlen($OldToken) == 44) {
                    $content = array(
                        'pull_service' => 'login',
                        'msg' => 'Your account number is in:' . date('Y-m-d H:i:s') . 'stay' . $address . 'Log on at,If you do not sign in for yourself,Please change your password now!'
                    );
                    \umeng\Push::send($OldToken, 'unicast', $content, 'message', true);
                }
                Cache::set(self::$prefix . self::$userId, self::$headToken, self::$timeOut);
            }
        } else {
            Cache::set(self::$prefix . self::$userId, self::$headToken, self::$timeOut);
        }

 

5. APP client receives push for pop-up window prompt and exit processing.

 

6. Above are the push methods encapsulated according to the SDK of the alliance, including unicast, broadcast, skip application activity, skip web connection and so on.

 

Posted by OLG on Fri, 02 Aug 2019 18:04:07 -0700