一个账号同时只能在同一个设备上登陆
高洛峰
高洛峰 2016-11-11 10:20:39
0
3
2166

我用PHP实现一个账号只能同时在同一个设备登录,注意,不是同一个IP。
之前是在MYSQL的表中加了个显示是否登录了的字段,若登录了设置为1,退出设置为0.
但后来发现,强行关闭浏览器的时候就没办法把这个字段设置为0了!
想了很久没想出解决方案,后来在网上看到好像可以用redis来实现,于是这两天开始学redis。但发现这样学下去也没有什么思路啊。
所以上来请教一下,请问有谁有经验的可以说一下怎么实现吗?

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

全員に返信(3)
三叔

关于使用mysql的一种解决方法

如果不考虑效率,只需要在mysql中你原有的记录是否已登录的字段旁再增加过期时间和设备唯一标识符两个字段,将以前的判断是否登录的条件由“是否为1”变为“是否为1且未过期且设备唯一标识符一致”。每次用户有操作时都更新过期时间的值,如果一段时间没有操作,登录状态就可以“自动”过期,这样就可以解决你的“强行关闭浏览器的时候就没办法把这个字段设置为0了”的问题。

使用phpredis进行简单实现

如果你刚接触redis,且仅仅需要用redis做用户登录的控制,对于数据结构,你不是很了解,string类型即可满足你(如果可以,使用hash可能会更好)。

下面以phpredis扩展提供的相关类作为背景,进行描述:

假设某一用户id为100的账户登录,向redis中记录登录设备信息

connect($redisHost, $redisPort);
    $cacheName = 'deviceUUID:user'.$userId; 
    $deviceUUID = getDeviceUUID(); // 假设有 getDeviceUUID() 函数用于获取/生成设备的唯一标识符
    $timeout = 600; // 用户10十分钟无操作自动下线
    $redis->set($cacheName, $deviceUUID);
    $redis->setTimeout($cacheName, $timeout);
}

设备每次执行其它操作前,都需要更新redis中设备信息的过期时间

connect($redisHost, $redisPort);
    $cacheName = 'deviceUUID:user'.$userId; 
    $deviceUUID = getDeviceUUID(); // 假设有 getDeviceUUID() 函数用于获取/生成设备的唯一标识符
    $timeout = 600; // 用户10十分钟无操作自动下线
    $cachedDeviceUUID = $redis->get($cacheName);
    $isTimeout = false === $cachedDeviceUUID;
    $isTheRightDevice = $deviceUUID === $cachedDeviceUUID;
    if($isTimeout || !$isTheRightDevice){
        return false;
    }
    $redis->setTimeout($cacheName, $timeout);
    return true;
}

设备中用户账户退出时,需要清理redis中的该设备信息

connect($redisHost, $redisPort);
    $cacheName = 'deviceUUID:user'.$userId; 
    $redis->delete($cacheName);
}

当然了,上面的使用string类型而不是散列类型来实现的解决方案在资源利用和效率上是不太合理的。如果你希望对redis有更深的了解和运用推荐你阅读《Redis IN ACTION》这本书。具体到php中使用redis,你可以选择使用phpredis扩展或predis。

いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!