前言
網紅啾啾鞋日前在他的 youtube 上放了個影片
說明他在 hahow 的線上課程在蝦皮上被盜賣的事情
其中影片的最後甚至實際測試了一波
發現 hahow 在網站上並無做多重登入的阻擋
也就是說 某A 和 某B 是可以同時登入同一個帳號來觀看線上課程
進而影響到內容創作者的權益
其實我覺得這種事是見人見智啦
就像是我買了一本書後 我也可以把這本書借給其他人讀
或是開個讀書會 大家一起讀
不過不管怎樣樣
多重登入就是不對
現在像是 Netflix、KKbox、PPT 等都有做多重登入的阻擋
就讓我們來看看怎麼阻擋多重登入吧
粗流
以下說明一下大致的流程
step 1
某 A
登入帳號時,建立 session紀錄下
Session ID
及 User ID
step 2
某 B
登入時,檢查 session,查看其 User ID
是否已經登入若有,則清除該 session,並新增
User ID
至 session 內若無,則直接新增
User ID
至 session 內
step 3
加入即時檢查 user 是否仍在登入狀態的確認機制
程式碼 (ORM以 meedo 為例)
第一洞,建立 session table
欄位有: id、session_id、user_id
第二洞,每次登入時呼叫 checkPreviousLogin
確認是否有用同一帳號登入過,並回傳前一個登入者的 user_id
public static function checkPreviousLogin($sid, $currentUserID)
{
$previousLoginUserID = mh()->get('session', [
"userID"
], [
"session_id[!]" =>$sid,
"userID" => $currentUserID
]);
return $previousLoginUserID;
}
第三洞,若有重複登入,清除該筆 session,並在本筆 session 內加入 errorMessage
public static function kickOut($previousUserID)
{
mh()->delete('session', [
'userID' => $previousUserID
]);
return true;
}
f3()->set('SESSION.statusMsg', ["xxxxx重複登入xxxxxx,xxxxxxxxxxx"]);
第四洞,將 session_id 與對應的 user_id 寫入 session 表內
public static function updateUserID($sid, $currentUserID)
{
mh()->update('session', [
'userID' => $currentUserID,
'stamp' => time()
], [
'session_id' => $sid
]);
return true;
}
第五洞,檢查在 session 內是否有 errorMessage
若有,則代表已重複登入,系統會顯示把前一個登入者踢掉的訊息,並把該 errorMessage 清掉
$msg = f3()->get('SESSION.statusMsg');
if (!empty($msg)) {
$output['msg'] = $msg;
f3()->clear('SESSION.statusMsg');
}
第六洞,每三分鐘檢查是否仍登入,若否,則 redirect 至首頁
checkDoubleLogin() {
if (app.member.loginCheckTimer !== undefined) {
return;
}
app.member.loginCheckTimer = window.setInterval(function() {
let callback = function() {
if (this.code === 0) {
return;
} else {
app.modal.show({
src: 'message-modal',
message: {
content: '系統偵測帳戶已重複登入,將在三秒後強制登出',
}
});
setTimeout(function() {
window.location.href = `${window.location.origin}/home`;
}, 3000);
}
};
gee.yell("member/check", {}, callback, callback)
}, 180000);
},