如何设计一个安全的登录接口?

article/2025/9/18 10:38:28

Java技术栈

www.javastack.cn

关注优质文章

作者:哒哒哒哒打代码
链接:juejin.im/post/6859214952704999438

前言

大家学写程序时,第一行代码都是hello world

但是当你开始学习WEB后台技术时,很多人的第一个功能就是写的登录(小声:别人我不知道,反正我是)。

但是我在和很多工作经验较短的同学面试或沟通的时候,发现很多同学虽然都有在简历上写:负责项目的登录/注册功能模块的开发和设计工作,但是都只是简单的实现了功能逻辑,在安全方面并没有考虑太多。

这篇文章主要是和大家聊一聊,在设计一个登录接口时,不仅仅是功能上的实现,在安全方面,我们还需要考虑哪些地方。

安全风险

暴力破解!

只要网站是暴露在公网的,那么很大概率上会被人盯上,尝试爆破这种简单且有效的方式:通过各种方式获得了网站的用户名之后,通过编写程序来遍历所有可能的密码,直至找到正确的密码为止。

伪代码如下:

# 密码字典  
password_dict = []  
# 登录接口  
login_url = ''  
def attack(username):  for password in password_dict:  data = {'username': username, 'password': password}  content = requests.post(login_url, data).content.decode('utf-8')  if 'login success' in content:  print('got it! password is : %s' % password)  

那么这种情况,我们要怎么防范呢?

验证码

有聪明的同学就想到了,我可以在它密码错误达到一定次数时,增加验证码校验!比如我们设置,当用户密码错误达到3次之后,则需要用户输入图片验证码才可以继续登录操作:

伪代码如下:

fail_count = get_from_redis(fail_username)  
if fail_count >= 3:  if captcha is None:  return error('需要验证码')  check_captcha(captcha)  
success = do_login(username, password)  
if not success:  set_redis(fail_username, fail_count + 1)  

伪代码未考虑并发,实际开发可以考虑加锁。

这样确实可以过滤掉一些非法的攻击,但是以目前的OCR技术来说的话,普通的图片验证码真的很难做到有效的防止机器人(我们就在这个上面吃过大亏)。

当然,我们也可以花钱购买类似于三方公司提供的滑动验证等验证方案,但是也并不是100%的安全,一样可以被破解(惨痛教训)。

登录限制

那这时候又有同学说了,那我可以直接限制非正常用户的登录操作,当它密码错误达到一定次数时,直接拒绝用户的登录,隔一段时间再恢复。

比如我们设置某个账号在登录时错误次数达到10次时,则5分钟内拒绝该账号的所有登录操作。

伪代码如下:

fail_count = get_from_redis(fail_username)  
locked = get_from_redis(lock_username)  if locked:  return error('拒绝登录')  
if fail_count >= 3:  if captcha is None:  return error('需要验证码')  check_captcha(captcha)   
success = do_login(username, password)  
if not success:  set_redis(fail_username, fail_count + 1)  if fail_count + 1 >= 10:  # 失败超过10次,设置锁定标记  set_redis(lock_username, true, 300s)  

umm,这样确实可以解决用户密码被爆破的问题。但是,这样会带来另一个风险:攻击者虽然不能获取到网站的用户信息,但是它可以让我们网站所有的用户都无法登录!

攻击者只需要无限循环遍历所有的用户名(即使没有,随机也行)进行登录,那么这些用户会永远处于锁定状态,导致正常的用户无法登录网站!用户密码怎么加密存储?这篇推荐看下。

IP限制

那既然直接针对用户名不行的话,我们可以针对IP来处理,直接把攻击者的IP封了不就万事大吉了嘛。

我们可以设定某个IP下调用登录接口错误次数达到一定时,则禁止该IP进行登录操作。

伪代码如下:

ip = request['IP']  
fail_count = get_from_redis(fail_ip)  
if fail_count > 10:  return error('拒绝登录')  
# 其它逻辑  
# do something()  
success = do_login(username, password)  
if not success:  set_redis(fail_ip, true, 300s)  

这样也可以一定程度上解决问题,事实上有很多的限流操作都是针对IP进行的,比如niginx的限流模块就可以限制一个IP在单位时间内的访问次数。感兴趣的可以关注公众号Java技术栈搜索阅读。

但是这里还是存在问题:

  • 比如现在很多学校、公司都是使用同一个出口IP,如果直接按IP限制,可能会误杀其它正常的用户

  • 攻击者完全可以在IP被封后切换IP来攻击

手机验证

那难道就没有一个比较好的方式来防范吗?

当然有。

我们可以看到近些年来,几乎所有的应用都会让用户绑定手机,一个是国家的实名制政策要求,第二个是手机基本上和身份证一样,基本上可以代表一个人的身份标识了。所以很多安全操作都是基于手机验证来进行的,登录也可以。

  1. 当用户输入密码次数大于3次时,要求用户输入验证码(最好使用滑动验证

  2. 当用户输入密码次数大于10次时,弹出手机验证,需要用户使用手机验证码和密码双重认证进行登录

手机验证码防刷就是另一个问题了,这里不展开,以后再有时间再聊聊我们在验证码防刷方面做了哪些工作。感兴趣的可以关注公众号Java技术栈,第一时间推送。

伪代码如下:

fail_count = get_from_redis(fail_username)  if fail_count > 3:  if captcha is None:  return error('需要验证码')  check_captcha(captcha)   if fail_count > 10:  # 大于10次,使用验证码和密码登录  if dynamic_code is None:  return error('请输入手机验证码')  if not validate_dynamic_code(username, dynamic_code):  delete_dynamic_code(username)  return error('手机验证码错误')  success = do_login(username, password, dynamic_code)  if not success:  set_redis(fail_username, fail_count + 1)  

我们结合了上面说的几种方式的同时,加上了手机验证码的验证模式,基本上可以阻止相当多的一部分恶意攻击者。但是没有系统是绝对安全的,我们只能够尽可能的增加攻击者的攻击成本。

大家可以根据自己网站的实际情况来选择合适的策略。

中间人攻击?

什么是中间人攻击

中间人攻击(man-in-the-middle attack, abbreviated to MITM),简单一点来说就是,A和B在通讯过程中,攻击者通过嗅探、拦截等方式获取或修改A和B的通讯内容。

举个栗子:小白小黄发快递,途中要经过快递点A,小黑就躲在快递点A,或者干脆自己开一个快递点B来冒充快递点A。然后偷偷的拆了小白小黄的快递,看看里面有啥东西。甚至可以把小白的快递给留下来,自己再打包一个一毛一样的箱子发给小黄

那在登录过程中,如果攻击者在嗅探到了从客户端发往服务端的登录请求,就可以很轻易的获取到用户的用户名和密码。

HTTPS

防范中间人攻击最简单也是最有效的一个操作,更换HTTPS,把网站中所有的HTTP请求修改为强制使用HTTPS。为什么 HTTPS 是安全的?推荐大家看下这篇。

为什么HTTPS可以防范中间人攻击?HTTPS实际上就是在HTTP和TCP协议中间加入了SSL/TLS协议,用于保障数据的安全传输。相比于HTTP,HTTPS主要有以下几个特点:

  • 内容加密

  • 数据完整性

  • 身份验证

具体的HTTPS原理这里就不再扩展了,大家可以关注下公众号Java技术栈进行搜索阅读。

加密传输

在HTTPS之外,我们还可以手动对敏感数据进行加密传输:

  • 用户名可以在客户端使用非对称加密,在服务端解密

  • 密码可以在客户端进行MD5之后传输,防止暴露密码明文

其它

除了上面我们聊的这些以外,其实还有很多其它的工作可以考虑,比如:

  • 操作日志,用户的每次登录和敏感操作都需要记录日志(包括IP、设备等)

  • 异常操作或登录提醒,有了上面的操作日志,那我们就可以基于日志做风险提醒,比如用户在进行非常登录地登录、修改密码、登录异常时,可以短信提醒用户

  • 拒绝弱密码 注册或修改密码时,不允许用户设置弱密码

  • 防止用户名被遍历 有些网站在注册时,在输入完用户名之后,会提示用户名是否存在。这样会存在网站的所有用户名被泄露的风险(遍历该接口即可),需要在交互或逻辑上做限制

  • ...

后记

现在国家不断的出台各种法律,对用户的数据越来越看重。

作为开发者,我们也需要在保护用户数据和用户隐私方面做更多的工作。后面我也会和大家聊一聊,我们在数据安全方面,做了哪些工作,希望可以给到大家一点点帮助。

关注Java技术栈看更多干货

戳原文,获取更多福利!


http://chatgpt.dhexx.cn/article/uDb3U9Ji.shtml

相关文章

[OS-Linux] CentOS 7.x 安全登录策略设置

简介 之前用用户名和密码登陆服务器 这样不安全 ,用SSH公钥(public key)验证 这个办法能很好的解决 登陆服务器 和安全登陆服务器的特点: 方法 / 步骤 🔐 一: 证书生成 命令行页面生成 (推荐) 查看执行结果,这时候连续回车即可…

开启QQ登录保护仍被盗号——QQ安全机制全面分析

1、前言 周围总是有些同学QQ被盗号,攻击者盗取账号后会继续去欺骗列表里的好友,形成链式反应。危害比较大。 腾讯QQ安全中心提供了登录保护机制,如图: 这是腾讯为QQ添加第二层保护,在开启登录保护后,盗号者…

使用 PHP 和 MySQL 的安全登录系统

Secure Login System with PHP and MySQL 在本教程中,我将教您如何创建自己的安全 PHP 登录系统。登录表单是您网站的访问者可以用来登录您的网站以访问受限内容(例如个人资料页面)的表单。我们将利用 MySQL 从数据库中检索帐户数据。 高级…

使用腾讯企业邮箱为什么强烈建议启用安全登录?怎么启用?

腾讯企业邮箱开启安全登录,简单来说就是把企业邮箱账号和微信绑定。启用安全登录和关闭安全登录,主要是登录方式发生了变化。 登录方式: 登录启用前启用后网页端邮箱帐号密码登录/微信扫码登录仅支持微信扫码登录客户端邮箱帐号密码登录仅…

登录安全----双重MD5加密实现安全登录

个人简介: 📦个人主页:肇事司机赵四 🏆学习方向:JAVA后端开发 📣种一棵树最好的时间是十年前,其次是现在! 🧡喜欢的话麻烦点点关注喔,你们的支持是我的最大动…

http登录模块加密登录安全登录方法

http请求很容易被截获,在写登录模块时,直接使用明文密码请求,很容易明文密码泄露;若在js页面对密码进行一次加密后在传输,虽不是明文密码,但也完全可以截获加密后的暗文,伪造http请求进行登录。…

安全登录认证

用户登录是任何一个应用系统的基本功能,特别是对于网上银行系统来说,用户登录的安全性尤为重要。如何设计一个网站的安全登录认证程序,是本文主要讨论的问题。 静态密码存在着比较多的安全隐患,攻击者有很多手段获得静态密码&…

Web登录如何确保安全

1、一个普通简单的HTML例子&#xff0c;用户登录信息是不安全的 <form action "http://localhost:8080/Application/login" method "POST"> 用户名&#xff1a;<input id"username" name"username" type"te…

实现安全登录的两种方法

登录安全——拦截器和过滤器或权限框架的使用 本次我们将采用两种方法实现登录的安全性&#xff0c;首先介绍拦截器和过滤器。 一、 过滤器和拦截器&#xff1a; 过滤器产生的时间/开始工作的时间&#xff1a; 进入Tomcat之后&#xff0c;但是在进servlet之前。Interceptor进入…

推荐几款优秀的搜素引擎

秘迹搜索 网址&#xff1a;https://mijisou.com/ 秘迹搜索是一款守护用户搜索信息的聚合搜索引擎&#xff0c;Ta不会根据搜索关键词追踪用户&#xff0c;也不会通过历史搜索内容做广告推荐。秘迹搜索通过聚合中文搜索服务比如Bing、百度、360、搜狗等搜索结果提供私密搜索服务…

12.推荐几款好用的搜索引擎

1.goobe https://goobe.io/ 专为程序员设计的搜索引擎&#xff08;搜索非技术相关的东西也很6&#xff09;&#xff0c;界面是这样事儿的 而且可以通过快照访问stackoverflow和github&#xff0c;非常好用 无广告&#xff0c;不跟踪 2.萌搜 https://mengso.com/ 号称小众的…

《搜索和推荐中的深度匹配》——1.1搜索和推荐

重磅推荐专栏&#xff1a; 《Transformers自然语言处理系列教程》 手把手带你深入实践Transformers&#xff0c;轻松构建属于自己的NLP智能应用&#xff01; 随着Internet的快速发展&#xff0c;当今信息科学的基本问题之一变得更加重要&#xff0c;即如何从通常庞大的信息库中…

基于Elasticsearch实现搜索推荐

在基于Elasticsearch实现搜索建议一文中我们曾经介绍过如何基于Elasticsearch来实现搜索建议&#xff0c;而本文是在此基于上进一步优化搜索体验&#xff0c;在当搜索无结果或结果过少时提供推荐搜索词给用户。 背景介绍 在根据用户输入和筛选条件进行搜索后&#xff0c;有时…

五个小众好用的搜索引擎

一、wikiHow https://zh.wikihow.com/ 我把wikiHow当做一个帮我做任何事的搜索引擎 wikiHow上每一篇详尽明了的指南文章 都能改善成百上千人的生活 与维基百科类似&#xff0c;wikiHow 也采用了维基技术 所有人都可以创建或编辑文章中的内容 来自全球的协作者们已编写了…

阿里搜索推荐系统

一、系统框架 导购升级的优化思路从三个方向着手&#xff1a;1.策略升级。利用深度学习及异构网络的思想&#xff0c;对用户个性化进行更深的理解和建模&#xff1b;同时对因马太效应引起的独立query数下降等问题进行优化。 2.导购外投。在包括会场激活页、猜你喜欢等渠道进行搜…

推荐和搜索系统的多样性研究综述

前言 检索结果的多样化是检索系统的一个重要研究课题&#xff0c;其可以满足用户的各种兴趣和供应商的平等公平曝光。 然而&#xff0c;检索系统中&#xff08;搜索与推荐领域&#xff09;的多样性研究缺乏一个系统的汇总&#xff0c;并且研究点相对零散。本次介绍的paper中&am…

从零开始搭建搜索推荐系统(五十二)ElasticSearch搜索利器

聊的不止技术。跟着小帅写代码&#xff0c;还原和技术大牛一对一真实对话&#xff0c;剖析真实项目筑成的一砖一瓦&#xff0c;了解最新最及时的资讯信息&#xff0c;还可以学到日常撩妹小技巧哦&#xff0c;让我们开始探索主人公小帅的职场生涯吧&#xff01; &#xff08;PS…

《智能搜索和推荐系统》总结

这本书主要分为4部分介绍&#xff0c;分别是搜索和推荐的基础&#xff0c;搜索系统基本原理&#xff0c;推荐系统的基本原理&#xff0c;工程应用。 第一部分&#xff1a;搜索和推荐的基础 主要讲了一下概率统计与应用数学的基础知识&#xff0c;比如概率论基础&#xff08;概率…

推荐系统与搜索引擎的差异

转自&#xff1a;https://blog.csdn.net/cserchen/article/details/50422553 详细分析推荐系统和搜索引擎的差异陈运文 从信息获取的角度来看&#xff0c;搜索和推荐是用户获取信息的两种主要手段。无论在互联网上&#xff0c;还是在线下的场景里&#xff0c;搜索和推荐这两种方…

商品搜索引擎---推荐系统设计

一、前言 结合目前已存在的商品推荐设计&#xff08;如淘宝、京东等&#xff09;&#xff0c;推荐系统主要包含系统推荐和个性化推荐两个模块。 系统推荐&#xff1a; 根据大众行为的推荐引擎&#xff0c;对每个用户都给出同样的推荐&#xff0c;这些推荐可以是静态的由系统管…