PHP를 사용하여 계정은 동시에 동일한 기기에만 로그인할 수 있다는 점을 기억하세요.
이전에 MYSQL 테이블에 로그인 여부를 표시하는 필드를 추가했는데, 로그인하면 1로, 로그아웃하면 0으로 설정됩니다.
그런데 나중에 브라우저가 강제로 닫힐 때 이를 변경할 수 있는 방법이 없다는 것을 알았습니다. 필드가 0으로 설정되었습니다!
오랜 시간 고민했지만 해결책이 떠오르지 않더군요. 나중에 인터넷을 보다가 redis를 이용해서 구현할 수 있을 것 같아 이틀만에 redis를 배우기 시작했습니다. 그런데 이렇게 공부를 계속하면 아무 소용이 없다는 걸 깨달았어요.
그래서 조언을 구하러 왔습니다. 경험 있으신 분, 구현 방법을 알려주실 수 있나요? 감사해요! 모두들 행복한 중추절 보내세요!
PHP를 사용하여 계정은 동시에 동일한 기기에만 로그인할 수 있다는 점을 기억하세요.
이전에 MYSQL 테이블에 로그인 여부를 표시하는 필드를 추가했는데, 로그인하면 1로, 로그아웃하면 0으로 설정됩니다.
그런데 나중에 브라우저가 강제로 닫힐 때 이를 변경할 수 있는 방법이 없다는 것을 알았습니다. 필드가 0으로 설정되었습니다!
오랜 시간 고민했지만 해결책이 떠오르지 않더군요. 나중에 인터넷을 보다가 redis를 이용해서 구현할 수 있을 것 같아 이틀만에 redis를 배우기 시작했습니다. 그런데 이렇게 공부를 계속하면 아무 소용이 없다는 걸 깨달았어요.
그래서 조언을 구하러 왔습니다. 경험 있으신 분, 구현 방법을 알려주실 수 있나요? 감사해요! 모두들 행복한 중추절 보내세요!
Redis라면 해시 구조를 이용해 계정 로그인 정보를 저장할 수 있습니다.
해시 구조: 키 필드 값
해시 관련 명령 http://redisdoc.com/hash/inde...
상세 구현:
해시 구조에서 동일한 키 필드를 사용하여 데이터를 쓰는 경우 과거 데이터를 덮어쓰게 됩니다
<code class="bash"> Redis> hset key field Test Redis> hget key field "Test" Redis> hset key field Run Redis> hget key field "Run" </code>
이러한 방식으로 단일 계정의 요구 사항을 실현할 수 있습니다. 해당 필드는 각 계정의 기본 키이며 이전 로그인 정보는 삭제됩니다. 로그인 정보가 무효화됩니다. 이렇게 하면 이전 로그인 상태가 무효화됩니다.
다른 기기의 로그인을 고려하는 경우 해당 필드를 devicename-uid 형식으로 변경하여 기기에 하나의 로그인 정보만 존재하도록 할 수 있습니다.
당신에게 필요한 것이 무엇인지 알고 싶으십니까?
Single Sign-On 또는 단일 장치 제한
단일 장치는 여러 브라우저가 있는 동일한 컴퓨터입니까?
mysql 사용에 대한 솔루션
효율성을 고려하지 않는다면 만료시간과 기기고유식별자만 추가하면 되는데, 두 필드는 "1인지 아닌지"에서 로그인 여부를 판단하는 이전 조건을 변경한다. "를 "1이고 만료되지 않았으며 고유 장치 식별자가 일치하는지 여부"입니다. 사용자가 작업을 수행할 때마다 만료 시간 값이 업데이트됩니다. 일정 시간 동안 작업이 없으면 로그인 상태가 "자동으로" 만료될 수 있습니다. 브라우저를 닫습니다." 이 필드를 0으로 설정하십시오."
간단한 구현을 위해 phpredis 사용을 처음 사용하고
만 사용하여 사용자 로그인을 제어해야 하지만 데이터 구조에 대해 잘 모르는 경우 redis
유형이 만족할 수 있습니다(가능하면 redis
아마도 더 나을 것입니다). string
hash
다음은 phpredis Extension에서 제공하는 관련 클래스를 배경으로 설명합니다.
用户id
<code class="php"><?php /** * 注册用户登录设备信息 * * 登录后向redis中写入登录的设备标识信息,如果在此之前已经登录了别的设备,之前登录的设备将被强制下线 */ function registerUserDevice() { $userId = 100; // 假设用户id为100 $redis = new Redis(); $redisHost = '127.0.0.1'; $redisPort = 6379; $redis->connect($redisHost, $redisPort); $cacheName = 'deviceUUID:user'.$userId; $deviceUUID = getDeviceUUID(); // 假设有 getDeviceUUID() 函数用于获取/生成设备的唯一标识符 $timeout = 600; // 用户10十分钟无操作自动下线 $redis->set($cacheName, $deviceUUID); $redis->setTimeout($cacheName, $timeout); }</code>
기기의 사용자 계정이 로그아웃되면 Redis의 기기 정보를 삭제해야 합니다
<code class="php"><?php /** * 延长redis中设备标识信息的生存时间 * * 重新设置redis中用户设备标识信息的过期时间 * @return bool true = 更新成功, false = 更新失败,当前设备需要重新登录 */ function extendDeviceInfoTTL() { $userId = 100; // 假设用户id为100 $redis = new Redis(); $redisHost = '127.0.0.1'; $redisPort = 6379; $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; }</code>
물론, 해시 유형 대신 문자열 유형을 사용하는 위의 솔루션은 리소스 활용 및 효율성 측면에서 합리적이지 않습니다. Redis에 대해 더 깊이 이해하고 적용하고 싶다면 "Redis IN ACTION"이라는 책을 읽어보시길 권합니다. PHP에서 redis를 사용하는 경우 phpredis 확장 또는 predis를 사용하도록 선택할 수 있습니다.
<code class="php"><?php /** * 销毁用户设备信息 * * 用在执行登出操作时 */ function delUserDevice() { $userId = 100; // 假设用户id为100 $redis = new Redis(); $redisHost = '127.0.0.1'; $redisPort = 6379; $redis->connect($redisHost, $redisPort); $cacheName = 'deviceUUID:user'.$userId; $redis->delete($cacheName); }</code>
얼마 전에 했던 프로젝트에는 아마도 이런 것이 있었을 것입니다. 일반적인 목적은 하나의 터미널만 이 계정에 로그인할 수 있다는 것입니다. 즉, 하나의 계정이 동시에 여러 곳에 로그인할 수 없다는 것입니다.
해결책은 데이터베이스에 필드 토큰을 추가하는 것입니다. 로그인할 때마다 타임스탬프와 기타 항목을 기반으로 새 토큰이 생성됩니다. 토큰이 변경되면 지속적으로 감지됩니다. 사용자가 다른 곳에 로그인했습니다.
데이터베이스에 필드를 추가합니다. 임시 토큰은 로그인 후 무작위로 생성되며, 사용자는 다른 장치에 로그인할 때 이 토큰을 기반으로 해당 세션을 생성합니다. 원본 장치의 세션은 데이터베이스 토큰과 일치할 수 없습니다. 자동으로 빠져 나옵니다.