福哥答案2020-01-15:
1、我想到的答案。
爲何不能用設備id?
接口調用,若是是網頁,設備id是沒法獲取的。另外,設備id能夠做假。redis
爲何不能用ip區分?
有些網絡(某些校園網),對外就是一個ip。服務器
用token區分設備有什麼缺點?
同一臺設備登陸屢次,會被當成多個不一樣的設備。實在想不到好的辦法,故邏輯實現採用token區分設備。cookie
邏輯實現以下:
方案1:用redis裏的list,key存【用戶id】,value存【登陸token】列表。用redis裏的string,key存【登陸token】,value存【登陸時間】。30天免登,string中value值是不是30天之前,若是是30天之前,能夠刪掉string中的這個token,list中對應的token也須要刪除。踢掉第1個,當用戶數超過兩個,踢掉list的第1個token,string中的token也須要刪除。改密碼,刪除某個用戶下的list以及string裏的對應token。
方案2:用redis裏的list,key存【用戶id】,value存【登陸token+時間】列表。網絡
2、知乎答案:
使用 Redis 存儲用戶 ,登陸的設備實現,利用 ZSET。
每一個用戶一個 ZSET(假設就是以用戶 id 做爲 ZSET 的 KEY),裏面的 KEY 爲設備 id,value 爲登陸時間戳。
1.當用戶登陸時,使用 lua 腳本(防止併發致使登陸設備多於 2 個)檢查設備:
ZSCORE 判斷設備是否存在以及登陸時間
若是存在:
ZADD就更新SCORE爲當前時間戳
若是不存在:
ZCARD 用戶id 獲取當前用戶有多少設備
若是設備數量 >= 2 則移除除了最後一個的其餘設備(能夠經過ZRANGE獲取最後一個KEY,ZSCORE獲取其分數以後ZREMRANGEBYSCORE刪除小於這個分數的全部KEY)
ZADD設置設備id爲KEY,當前時間戳爲SCORE
設置ZSET過時時間爲30天,減小30天內沒有設備登陸時檢查登陸態的判斷消耗併發
2.當用戶請求須要登陸態後的 API,檢查登陸態時:
ZSCORE 判斷設備是否存在以及登陸時間
若是設備存在存在而且登陸時間與當前時間間隔小於30天,則有效。
不然,登陸態失效,須要從新登陸lua
3.修改密碼,全部設備下線:
刪除這個ZSETblog
3、享學答案:
1.要可以識別不一樣的設備,好比移動設備的imei。
2.服務端須要有存儲帳號與設備的記錄,以及客戶端的ip及端口。
對因而否登出的檢測有主動和被動兩種方式。
3.服務端主動調用客戶端登出。
3.1客戶端能夠開放清楚客戶端cookie等登陸信息的接口。
3.2.服務端在登陸時存入設備與用戶的記錄,而且判斷是否超出限制,若是超出限制則找出最先登陸的客戶端ip端口調用清楚客戶端cookie的接口。
3.4.修改密碼同理,調用全部已登陸客戶端的清楚cookie接口。
4.客戶端主動檢測登陸是否已失效。
4.1服務端須要有檢測登陸有效性的接口。
4.2客戶端在接到請求時主動調用服務器接口檢測,根據響應判斷當前登陸狀態,若是已失效則主動退出當前帳號。
4.3登陸超出限制或者修改密碼時,服務端刪除帳號與設備的記錄,在客戶端調用登陸有效性檢測接口時查不到對應設備的記錄則返回已失效。token
2020-01-15:用戶登陸,保存30天的免登,只容許兩個設備登陸,若是有第三個設…如何回答呢?
2020-01-15:用戶登陸,保存30天的免登,只容許兩個設備登陸,若是有第三個設備登陸,踢掉第一個。改密碼的時候,全部設備須要下線。這個邏輯怎麼實現呢?
評論接口