异地登陆验证的简单实现
書到用時方恨少。最近遇到一個功能點:從日志表中將記錄每個用戶的IP信息收集統(tǒng)計到用戶白名單項。
這個功能只執(zhí)行一次(初始化),但數(shù)據(jù)量可能較大,執(zhí)行java代碼/python腳本較慢。正當(dāng)我不知所措和我的小伙伴考慮用存儲過程完成時,范總輕描淡寫的說,不就是一句SQL嘛,那么復(fù)雜干啥?
滿臉問號,我設(shè)想的最簡單的方案都需要兩個for循環(huán)的嵌套,一個SQL可以解決?
這時候明哥告訴我了一個函數(shù):group_concat。正是這個函數(shù),瞬間解決了我的問題。
1. 需求
想要實現(xiàn)一個用戶白名單功能,以減少異地驗證的頻率,減少短信費用的支出, 提升用戶登陸體驗。
2. 實現(xiàn)原理
由于之前沒有接觸過類似的功能,本次實現(xiàn)方法為:在用戶表中新增用戶IP白名單字段,用于存儲用戶登陸后的IP的前三位;在登陸時判斷是否在一個城市中。這個辦法相對而言比較笨,有些城市擁有的IP地址跨度較大。之后有空再寫方法來分辨確切的省市自治區(qū)吧。也歡迎大佬們指導(dǎo),讓我學(xué)習(xí)下其他的驗證方式。
3. 導(dǎo)入數(shù)據(jù)
之前的版本中,使用了較大的表來記錄用戶對接口的調(diào)用記錄,其中包括了用戶ID和用戶IP信息。在這個表中,一個用戶對應(yīng)多行記錄,一個IP也可以對應(yīng)多條記錄(也可能對應(yīng)多個賬戶)。我下意識就想寫一個java項目或者python腳本完成這個工作。但是java工具需要建立Java項目確定依賴情況;python原生鏈接數(shù)據(jù)庫進(jìn)行處理較慢(數(shù)據(jù)量大)。我和小林進(jìn)行討論后,覺得還是寫一個存儲過程解決比較簡單靠譜。
就在準(zhǔn)備動手的時候,我和明哥抱怨了一句:這么復(fù)雜的功能,一個SQL怎么可能完成?。明哥了解我的需求后,表示一個SQL足夠完成數(shù)據(jù)整理導(dǎo)入用戶表,并向我推薦了一個函數(shù):group_concat。
group_concat,與concat類似,用于字符串的拼接。但與concat應(yīng)用場景不同,group_concat主要適用于在group by語句中拼接分類后的結(jié)果字段。基本語法為:
group_concat( [distinct] 待連接字段 [order by 排序字段 asc/desc ] [separator '分隔符'] )
將其置入查詢語句的select 之后,就可以輕易的完成批量獲取用戶分組后的IP信息了。
select SELECT create_user_id, group_concat( DISTINCT concat( '#', SUBSTRING_INDEX ( ip_address, '.', 3 ) ) SEPARATOR '' ) FROM sys_log GROUP BY create_user_id;
為了符合設(shè)計(設(shè)計的IP白名單格式為#xxx.xxx.xxx):使用SUBSTRING_INDEX函數(shù)獲取了第三個’.’之前的字符串;使用concat將’#’拼接到切割后的IP字段之前;使用group_concat函數(shù)中的SEPARATOR關(guān)鍵字將默認(rèn)的逗號(’,’)分隔符替換為空。執(zhí)行之后,就只有用戶ID和指定格式的用戶IP白名單了。
對于修改用戶表,可以直接將上述的sql放置在update語句中,增加一些判斷,則一個SQL就完成了IP地址的轉(zhuǎn)儲:
update sys_user a
set a.address_ip = (SELECT group_concat(distinct concat('#', SUBSTRING_INDEX(ip_address, '.', 3)) separator '')
FROM sys_log b
where b.create_user_id = a.id
group by create_user_id);
END~
參考資料:
Chapter 12 Functions and Operators-Mysql官方文檔
感謝明哥、小林提出的幫助
歡迎聯(lián)系我一起學(xué)習(xí)討論~
mail: wgh0807@qq.com
微信: hello-wgh0807
qq: 490536401
總結(jié)
以上是生活随笔為你收集整理的异地登陆验证的简单实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数学三考试大纲
- 下一篇: 不能访问共享的文件,电脑提示“您没有权限