ThinkPHP中不允许用户在多个设备登录的方法

{{ time }}

Step1 在用户数据表中加一个字段last_login, 用来记录用户登录时间戳

Step2 在每次登录时, 在Session和数据表中同时记录登录时间, 所以doLogin()方法中的部分示例代码如下

  //验证通过以后,先生成一个登录时间
  $loginTime = time();

  //session操作
  session('user', $res);
  session('user')['login_time'] = $loginTime; //记录登录时间

  //把登录时间更新入数据库
  db('userx')
     ->where('username', 'eq', $username)
     ->setField('last_login', $loginTime);
 
 echo 'loginSuccess';

Step3 在需要检测是否已经在其他设备登录的页面, 其控制器继承IndexBase基类, 不再继承Controller基类; 如果IndexBase基类没有, 就建立一个

Step4 在IndexBase中建立一个方法checkOtherLogin(), 用来检测是否已在其他设备登录. IndexBase的示意代码如下

<?php

namespace app\index\controller;

use think\Controller;

class IndexBase extends Controller
{
    //功能: 检测是否在另一设备登录
    protected function checkOtherLogin(){
        if (session('user')) {
            $userId=session('user')['id'];
            
            //取得session中的登录时间
            $loginTimeIs=session('user')['login_time'];

            //取得数据库里的登录时间
            $loginTimeIb=db('userx')
                ->where('id','eq',$userId)
                ->find()['last_login'];

            //它们不同的则退出登录, 并跳转至首页
            if($loginTimeIs!=$loginTimeIb){
                session('user', null);
                $this->redirect(url('index/index/index',['from'=>'otherLogin']));
            }
        }
    }

    // 初始化方法
    protected function _initialize()
    { 
        $this->checkOtherLogin();
    }
}