用户被盗号?你肯定缺少这些设计

前言

在之前的文章【你的登录接口真的安全吗?】中,我们在用户登录安全方面做了很多设计,就是保护用户的账号安全,但是!!我相信做过用户体系的开发或产品都知道,用户的密码泄漏是一个不可避免的事件,总会有用户因为各种奇奇怪怪的原因而导致账号被盗,进而导致用户信息泄漏、虚拟数据丢失、经济损失等各种后果。那针对这种场景,我们可以通过什么手段来尽量预防呢?

几种实现方式来判断用户登录环境

一般这种情况,业界最简单的处理方式就是识别用户登录环境是是否正常:比如是否是常登录IP、或者是常登录设备等,如果不是,那么则进行限制、二次验证、用户告警等操作。

异地登录

首先是用户异地登录,一般场景下,用户的使用环境大部分时间都是不怎么变化的,比如公司、家里、宿舍或学校等。那么我们可以基于用户的使用IP,来做风险管理。

伪代码实现

python 复制代码
   def login(username, password, ip):
      # 登录失败,简化其它流程
      if not do_login(username, password):
         return Result(100, '登录失败')

      # 检查用户登录环境异常
      if !check_login_env(username, ip):
         # 发送短信或邮件给用户,告知用户账号在非常用地登录
         send_notice(username, ip)
         # 前端收到这个状态码后跳转到二次验证页面
         return Result(101, '非常登录地登录')

      # 登录成功,异步记录当前ip
      async_log_ip(username, ip)
      return Result(0, '登录成功')

流程很简单,用户登录成功后,进行一次环境校验,判断用户当前登录ip是否为常登录地,如果不是,那么先给用户发送邮件或短信通知,然后返回对应状态码给前端,跳转到二次校验的页面。

二次校验可以通过APP扫码、手机验证码等方式登录。

*上面的代码中还缺少很重要的一步操作,怎么判断用户的IP是否是常登录IP?我们可以基于IP来实现,但是我们现在家用网络的IP基本上都不是固定IP,所以实际场景下可能更多的是使用地区来判断,比如城市。

伪代码实现

python 复制代码
   def check_login_env(username, ip):
      cur_city = get_city_from_ip(ip)
      # 此城市是否在近半年的常登录城市中
      city = get_last_half_year_cities(username)
      return cur_city == city


   def log_env(username, ip):
      city = get_city_from_ip(ip)
      # 记录当前登录城市 
      insert_login_ip(username, city, ip, datetime.now())
      # 统计常登录城市
      # 查询的近半年登录次数最多的城市
      city = select_max_login_city_last_half_year()
      # 设置常登录城市
      set_last_half_year_cities(username, city)

上面只是简单的实现,整个判断过程比较粗糙,准确性也不够高。实际产生中,我们可以根据ip位置,结合算法来计算常登录地;或者结合下面的其它方式共同判断。

非常用设备登录

除了通过ip来判断用户使用环境外,我们一般还会结合用户设备来判断,特别是移动端应用,用户设备大部分时候是固定不变的。
设备信息一般可以使用设备指纹的方式,通过采集设备的各种信息,生成一个唯一标识,用于标识此设备。如果设备指纹不存在,那么证明用户在新设备上登录,则进行二次验证。

伪代码实现

python 复制代码
   def login(username, password, ip, device_info):
      # 登录失败,简化其它流程
      if not do_login(username, password):
         return Result(100, '登录失败')

      # 检查用户登录环境异常
      if !check_login_env(username, ip):
         # 发送短信或邮件给用户,告知用户账号在非常用地登录
         send_notice(username, ip)
         # 前端收到这个状态码后跳转到二次验证页面
         return Result(101, '非常登录地登录')

      if !check_device_env(username, device_info):
         send_notice(username, device_info)
         # 前端收到这个状态码后跳转到二次验证页面
         return Result(102, '正在使用新设备登录')

      # 登录成功,异步记录当前ip
      async_log_ip(username, ip)
      # 记录设备信息
      async_log_device(username, device_info)
      return Result(0, '登录成功')

用户设备信息采集需要征得用户同意,那万一无法采集信息怎么办? 我们也可以想办法在用户第一次登录时,在用户设备中生成记录一个唯一ID并存储在设备中,用于标记这个设备。

异常IP登录

这个和异地登录不同的是,我们可以维护一个IP黑名单,只要是用户登录的IP在黑名单内,则一定要求用户做二次验证。

黑名单的来源主要是通过购买、自行采集的方式获取到的黑产IP

用户风控

上面的各种方式,都不是孤立的,更多的是结合起来,包括其它更多的判断逻辑,来最终决定用户的登录环境是否存在风险,而这部分功能,我们一般会把它抽离出来,单独做为一个风控服务实现。 我们输入用户登录相关的数据,比如用户ID、登录IP、设备信息等,风控服务结合历史数据、用户行为数据等,通过大数据分析以及我们配置的风控规则,最终输出给我们一个风险级别,然后再根据风险级别决定是否需要做后续的措施。

总结

今天主要讲了几种预防用户账号被盗的手段以及简单的实现,相信大家在使用各种产品的时候也有碰到过对应的功能,我们在做用户体系设计的时候,前期可能用户量比较少,但是也可以尽量的考虑安全相关的设计,体量小有小的做法,大有大的做法,但是做了总比没做好。希望读完这篇文章大家有所收获~

相关推荐
Lizhihao_7 分钟前
JAVA-堆 和 堆排序
java·开发语言
极客先躯12 分钟前
高级java每日一道面试题-2025年3月21日-微服务篇[Nacos篇]-什么是Nacos?
java·开发语言·微服务
工业互联网专业20 分钟前
基于springboot+vue的动漫交流与推荐平台
java·vue.js·spring boot·毕业设计·源码·课程设计·动漫交流与推荐平台
雷渊23 分钟前
深入分析Spring的事务隔离级别及实现原理
java·后端·面试
Smilejudy32 分钟前
不可或缺的相邻引用
后端
惜鸟33 分钟前
Elasticsearch 的字段类型总结
后端
rebel34 分钟前
Java获取excel附件并解析解决方案
java·后端
微客鸟窝36 分钟前
Redis常用数据类型和命令
后端
熊猫片沃子38 分钟前
centos挂载数据盘
后端·centos
微客鸟窝39 分钟前
Redis配置文件解读
后端