给Django Admin添加验证码和多次登录尝试限制的实现


Posted in Python onJuly 26, 2020

Django自带的Admin很好用,但是放到生产环境总还差了点什么= =

看看admin的介绍:

Django奉行Python的内置电池哲学。它自带了一系列在Web开发中用于解决常见问题或需求的额外的、可选工具。这些工具和插件,例如django.contrib.redirects都必须在settings中的INSTALLED_APPS处进行注册,有的还需要执行manage.py migrate命令,在数据库中创建一些数据表。

Admin站点是Django有别于其它Web框架最重要的一点,并且非常受欢迎,简直是出门旅游xxxx的必备。不管你是写个小demo还是做个大项目都用得上。admin(下文中将Admin管理后台简称为admin)通过读取你的模型数据,快速构造出一个可以对实际数据进行管理的Web站点,常用于开发测试,简单管理等场合,适用于部门内部为工作方便的场合, 但不建议在生产环境中使用。

为什么不建议在生产环境使用呢,因为Admin缺了验证码和登录限制这种安全方面的功能!等会被人随便暴力破解就进后台了,那我们的系统安全性还怎么保障?

但是别急,我已经通过魔改的方式实现了验证码和登录限制了,现在可以愉快使用admin系统了。

先看看效果

给Django Admin添加验证码和多次登录尝试限制的实现

效果还是nice的,登录尝试次数可以自己设定,我这里就不演示了,输那么多次错误密码太麻烦了。

验证码

验证码我是用了 django-simple-captcha 这个库,配合 multi_captcha_admin 来生成验证码form,非常方便。

首先是pip安装这两个库,大家都懂的,不再赘述。

配置一下 settings.py

INSTALLED_APPS = [
  'multi_captcha_admin',
]
 
# 验证码配置
MULTI_CAPTCHA_ADMIN = {
  'engine': 'simple-captcha',
}

配置 urls.py

# 添加这一项
path('captcha/', include('captcha.urls')),

到了这步就好啦,如果用的是Django官方的Admin就直接能显示出登录的验证码了,不过我用的是第三方的Admin,所以需要手动添加form。

方法很简单,找到 login.html ,在登录的表单里面添加这一项就好了。

{{ form.captcha }}

默认生成的验证码和输入框是原生样式,比较丑~ 我们可以优化一下。我是用js把生成的图片和验证码输入框替换成elementUI的样式,有需要的小伙伴可以参考一下。

var row = document.querySelector('#captcha_group');
 
var captcha_img = document.querySelector('img.captcha');
var col_8 = document.createElement('el-col');
col_8.setAttribute(':span', '8');
col_8.appendChild(captcha_img);
 
var captcha_input = document.querySelector('#id_captcha_1');
var el_input = document.createElement('el-input');
var col_16 = document.createElement('el-col');
col_16.setAttribute(':span', '16');
el_input.setAttribute('name', captcha_input.getAttribute('name'));
el_input.setAttribute('v-model', 'captcha');
el_input.setAttribute('required', 'required');
el_input.setAttribute('placeholder', '请输入验证码');
col_16.appendChild(el_input);
 
captcha_input.parentNode.removeChild(captcha_input);
 
row.appendChild(col_8);
row.appendChild(col_16);

登录限流

这个也不复杂,不过我一开始做还是花了比较长时间,查不到什么有用的资料,后面我去读了Django Admin的代码,一下就想出解决方法了哈哈~

通过admin的代码,我发现处理登录是 admin.site.login(request, extra_context) 这个方法,那问题就变得很简单了,给他加一个装饰器就好了,不过我们不能去修改框架的代码,所以自己写一个新的view,如下:

# 覆盖默认的admin登录方法实现登录限流
@ratelimit(key='ip', rate='5/m', block=True)
def extend_admin_login(request, extra_context=None):
  return admin.site.login(request, extra_context)

然后在 urls.py 里配置一下,记得要放在 admin 的前面:

urlpatterns = [
  path('admin/login/', views.extend_admin_login),
  path('admin/', admin.site.urls),
]

这样就可以实现限流了,这里要介绍一下 ratelimit 这个装饰器,这是django-ratelimit这个包提供的,为了使用这个包,需要配置redis缓存,附上配置代码:

# 配置redis缓存
CACHES = {
  'default': {
    'BACKEND': 'django_redis.cache.RedisCache', # 缓存后端 Redis
    # 连接Redis数据库(服务器地址)
    # 一主带多从(可以配置个Redis,写走第一台,读走其他的机器)
    'LOCATION': [
      'redis://localhost:6379/0',
    ],
    'KEY_PREFIX': 'milky', # 项目名当做文件前缀
    'OPTIONS': {
      'CLIENT_CLASS': 'django_redis.client.DefaultClient', # 连接选项(默认,不改)
      'CONNECTION_POOL_KWARGS': {
        'max_connections': 512, # 连接池的连接(最大连接)
      },
    }
  }
}

@ratelimit(key='ip', rate='5/m', block=True)key=ip 表示根据ip来区分, rate=5/m 表示一分钟最多请求这个接口5次, block=true 表示超过这个限制就直接拦截,如果没有设置block参数的话,超过限制也不会拦截,但是可以在ratelimit计数器里面看到请求的次数。

更多用法可以看官方文档: https://django-ratelimit.readthedocs.io/en/stable/index.html

参考资料

https://github.com/a-roomana/django-multi-captcha-admin

https://django-simple-captcha.readthedocs.io/en/latest/advanced.html#rendering

到此这篇关于给Django Admin添加验证码和多次登录尝试限制的实现的文章就介绍到这了,更多相关Django Admin验证码和登录限制内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python数据抓取分析的示例代码(python + mongodb)
Dec 25 Python
python之文件读取一行一行的方法
Jul 12 Python
python实现汉诺塔算法
Mar 01 Python
Python分割指定页数的pdf文件方法
Oct 26 Python
Python数据类型之List列表实例详解
May 08 Python
Python 实现交换矩阵的行示例
Jun 26 Python
Flask框架模板继承实现方法分析
Jul 31 Python
Python 字符串池化的前提
Jul 03 Python
Python可以用来做什么
Nov 23 Python
selenium携带cookies模拟登陆CSDN的实现
Jan 19 Python
Pandas加速代码之避免使用for循环
May 30 Python
python flask开发的简单基金查询工具
Jun 02 Python
python如何支持并发方法详解
Jul 25 #Python
Python获取浏览器窗口句柄过程解析
Jul 25 #Python
用Python 爬取猫眼电影数据分析《无名之辈》
Jul 24 #Python
基于Python实现简单学生管理系统
Jul 24 #Python
用python实现学生管理系统
Jul 24 #Python
Python 解析简单的XML数据
Jul 24 #Python
深入了解NumPy 高级索引
Jul 24 #Python
You might like
php+html5实现无刷新图片上传教程
2016/01/22 PHP
PHP模板引擎Smarty中的保留变量用法分析
2016/04/11 PHP
php cookie用户登录的详解及实例代码
2017/01/03 PHP
基于JQuery 的消息提示框效果代码
2011/07/31 Javascript
cookie 最近浏览记录(中文escape转码)具体实现
2013/06/08 Javascript
Javascript 按位左移运算符使用介绍(
2014/02/04 Javascript
IE6中链接A的href为javascript协议时不在当前页面跳转
2014/06/05 Javascript
对Web开发中前端框架与前端类库的一些思考
2015/03/27 Javascript
微信JSSDK上传图片
2015/08/23 Javascript
JavaScript 2048 游戏实例代码(简单易懂)
2016/03/25 Javascript
JS简单实现点击复制链接的方法
2016/08/03 Javascript
js通过keyCode值判断单击键盘上某个键,然后触发指定的事件方法
2017/02/19 Javascript
微信小程序 聊天室简单实现
2017/04/19 Javascript
详解基于node的前端项目编译时内存溢出问题
2017/08/01 Javascript
vue.js语法及常用指令
2017/10/29 Javascript
layui点击按钮添加可编辑的一行方法
2018/08/15 Javascript
node链接mongodb数据库的方法详解【阿里云服务器环境ubuntu】
2019/03/07 Javascript
vue如何实现自定义底部菜单栏
2019/07/01 Javascript
基于elementUI竖向表格、和并列的案例
2020/10/26 Javascript
在antd4.0中Form使用initialValue操作
2020/11/02 Javascript
[53:10]完美世界DOTA2联赛决赛日 FTD vs GXR 第二场 11.08
2020/11/11 DOTA
使用python和pygame绘制繁花曲线的方法
2018/02/24 Python
nginx黑名单和django限速,最简单的防恶意请求方法分享
2019/08/09 Python
Python中turtle库的使用实例
2019/09/09 Python
自适应线性神经网络Adaline的python实现详解
2019/09/30 Python
解决Pytorch 加载训练好的模型 遇到的error问题
2020/01/10 Python
基于梯度爆炸的解决方法:clip gradient
2020/02/04 Python
pycharm安装及如何导入numpy
2020/04/03 Python
python爬虫scrapy基于CrawlSpider类的全站数据爬取示例解析
2021/02/20 Python
基于HTML5代码实现折叠菜单附源码下载
2015/11/27 HTML / CSS
暇步士官网:Hush Puppies
2016/09/22 全球购物
FitFlop澳大利亚官网:英国符合人体工学的鞋类品牌
2017/06/05 全球购物
美国领先的机场停车聚合商:Airport Parking Reservations
2020/02/28 全球购物
空字符串(“”)和null的区别
2012/11/13 面试题
python之django路由和视图案例教程
2021/07/26 Python
node快速搭建后台的实现步骤
2022/02/18 NodeJs