此教程非权威,仅是个人搭建网站中探索的总结,留给后人的基本流程的简介
首先,确保你已经完成了django知识的学习, 以便不出现未经了解且不易理解的错误,本文不会叙述基础教程,如若此, 请跳转至djangoproject官网教程.
好了! 让我们开始探索的旅途!
CAPTCHA项目是Completely Automated Public Turing Test to Tell Computers and Humans Apart (全自动区分计算机和人类的图灵测试)的简称, CAPTCHA的目的是区分计算机和人类的一种程序算法,是一种区分用户是计算机和人的计算程序,这种程序必须能生成并评价人类能很容易通过但计算机却通不过的测试。 来源:百度百科及维基百科
Captcha 生成目标值, 并加入噪音, 计算机无法处理非固定模式的数据(请等下再反驳),而人类可识别生成的数据 Captcha 被广泛用于web, 用于在应用层清洗流量(比如爬虫,cc攻击),区分是否为有效流量, 减小服务器的负载。 比方说, 在用户注册, 用户登录, 匿名评论, 等等, 几乎与耗时, 高IO, 高计算挂钩的操作, 都与人机校验有着直接或间接的关系,即在服务器操作与用户之间起了一层保护 然而,随着时间的推移, 简单的数字字母计算已经不能够阻止网络攻击的脚步了。机器学习的进步,算力的提升, 攻击者可以用廉价的成本破解验证码。通过将标签化的数据卷积,获得校验值, 比如火爆的Captcha Solver 那么,作为防守方,最简单最物理的办法就是增大数据量,增大差异度, 让攻击方校验数据难度更大, 进攻成本更高, 所以 来源:个人总结
相信从名称上就看出来了, captcha包括但不限于reCaptcha, hCaptcha, 以及cloudflare的Turnstile.
因为google在中国大陆无法访问(虚拟专用网络vpn除外),相应的,作为google旗下的reCaptcha (三级域名 recaptcha.google.com) 也无法访问。虽说我们可以通过Header Editor跳转至recaptcha.net, 但用户操作不便, 除非你的网站有真实力, 否则正常用户不会为了注册一个小网站而大费周折
因此,世界内可访问国家数量更多的hCaptcha,是一个不错的选择
此为我的网站的登录界面
国内已经有许多相关的使用方法的文章, 我也不再赘述过多
原理大概可以总结为:
可以看出, simple-captcha直接与数据库挂钩,这样的好处是不会因内存崩溃而丢失数据,而相应的,每一次请求, 都要生成一次,永久保存与数据库中,而且每次查表数据量大, 如果查不到的话就更不妙了,这已经违背了我们至少是我使用验证码的初衷了。 并且查阅官网(django-simple-captcha.readthedocs.io)后并没有发现对缓存作为数据库的支持(也许是我没看到哈)。通过修改源码的方式, 我将其改为了:
(为个人总结,仅供参考) 这样, 大大减少I/O操作, 减轻MySQL负担, 通过和RAM而不是ROM的交换, 和NoSQL而不是SQL数据库, 提高性能,这也是缓存服务器存在的意义之一 那缺点也显而易见:大幅增加内存的增加比例,更易造成内存崩溃,丢失数据(虽然redis可以通过和硬盘缓存数据)。 即使如此,因为redis只需缓存key和value而不需图像(每条≈50bytes),所以不必过于担忧。(服务器1G内存需谨慎,2G需深思,4G需考虑,8G无视)
但是,我觉得还是不够完美,所以我有了以下方案
怎么样?是不是有一种似曾相识的感觉?这不就是OAuth2
的原理吗!
这样,直接抛弃数据库,大大减小服务器负载!
这里有一个文章可以参考 - https://www.leadong.com/id49631467.html 踩坑: 切记! 请在注册时将SECERT_KEY记下,后期难以查看。而SITE_SECERT则不用那么严格, 后期可以查看
相信你已经看到了, hCaptcha在reactJS, angularJS,springBoot, 包括<其他>中的django 的部署方式 顺着链接, 你应该看到了github上的django-hcaptcha项目,作者为AndrejZbin。好了!你可以不用看此文章了,直接通过README部署了hcaptcha!
那么,如果你还不不太懂,请继续看: 在python环境下载:
pip install django-hcaptcha
在 [project]/settings中设置:
INSTALLED_APPS = [
...
'hcaptcha', # <-- 新增此app
]
出于开发的目的,不需要进一步的配置。 在页面中的hCaptcha中会有此提示: 此验证码仅用于测试。如果你在网站中看到了这个提示,请联系管理员。
对于部署环境,您需要获得 hCaptcha 站点密钥和机密密钥,并将它们添加到您的设置中:
HCAPTCHA_SITEKEY = '<your sitekey>'
HCAPTCHA_SECRET = '<your secret key>'
在forms.py中使用:
from hcaptcha.fields import hCaptchaField
class Forms(forms.Form):
....
hcaptcha = hCaptchaField()
....
这是fields.py的源码, 其中, 变量_
是i18n的实现(前提是设置 i18n为真):
import inspect
import json
from urllib.error import HTTPError
from urllib.parse import urlencode
from urllib.request import build_opener, Request, ProxyHandler
from django import forms
from django.utils.translation import gettext_lazy as _
from hcaptcha.settings import DEFAULT_CONFIG, PROXIES, SECRET, TIMEOUT, VERIFY_URL
from hcaptcha.widgets import hCaptchaWidget
class hCaptchaField(forms.Field):
widget = hCaptchaWidget
default_error_messages = {
'error_hcaptcha': _('hCaptcha could not be verified.'),
'invalid_hcaptcha': _('hCaptcha could not be verified.'),
'required': _('Please prove you are a human.'),
}
def __init__(self, **kwargs):
superclass_parameters = inspect.signature(super().__init__).parameters
superclass_kwargs = {}
widget_settings = DEFAULT_CONFIG.copy()
for key, value in kwargs.items():
if key in superclass_parameters:
superclass_kwargs[key] = value
else:
widget_settings[key] = value
widget_url_settings = {}
for prop in filter(lambda p: p in widget_settings, ('onload', 'render', 'hl')):
widget_url_settings[prop] = widget_settings[prop]
del widget_settings[prop]
self.widget_settings = widget_settings
super().__init__(**superclass_kwargs)
self.widget.extra_url = widget_url_settings
def widget_attrs(self, widget):
attrs = super().widget_attrs(widget)
for key, value in self.widget_settings.items():
attrs['data-%s' % key] = value
return attrs
def validate(self, value):
super().validate(value)
opener = build_opener(ProxyHandler(PROXIES))
post_data = urlencode({
'secret': SECRET,
'response': value,
}).encode()
request = Request(VERIFY_URL, post_data)
try:
response = opener.open(request, timeout=TIMEOUT)
except HTTPError:
raise forms.ValidationError(self.error_messages['error_hcaptcha'], code='error_hcaptcha')
response_data = json.loads(response.read().decode("utf-8"))
if not response_data.get('success'):
raise forms.ValidationError(self.error_messages['invalid_hcaptcha'], code='invalid_hcaptcha')
注意! turnstile还在测试阶段!
通过 Turnstile,我们可以根据具体访问者/浏览器调整实际质询结果。首先,我们运行一系列小型非交互式 JavaScript 质询,从而收集更多关于访问者/浏览器环境的信号。这些质询包括工作证明、空间证明、Web API 探测,以及检测浏览器怪癖和人类行为的各种其他质询。因此,我们可以根据具体要求调整质询的难度。 此外,Turnstile 所采用的机器学习模型可以检测能够通过质询的最终访问者的共同特征。这些初始质询的计算难度可能因访问者而异,但目标是快速运行。
来自: blog.cloudflare.com/turnstile-private-captcha-alternative/
Turnstile的服务端校验原理和hCaptcha的差不多, 而客户端校验方式有一定区别 之前的方案优化都是在服务端考虑的,而此是为客户端服务考虑的 Turnstile 易部署(看下面就知道了),免费,国内可访问 而且有一些国外建的个人博客的验证码也用起来Turnstile了
我看截至2022/12/24 16:16,国内好像没太有关于Turnstile注册的文章,关于hCaptcha在django的使用方式更没太有教程,stackoverflow也没啥,因此顺便补个坑
首先确保你已经注册了cloudflare(百度一搜就有,毕竟cloudflare名声远扬)
🌾 菜单栏往下拉,找到还在测试阶段的turnstile
多种模式自行选择
🍋 接入Django 查看了turnstile的文档https://developers.cloudflare.com/turnstile/的Client-side render和Server-side validation, 发现api还挺简单
这里是第二天的zmh-program, 星期六时我发布了这篇文章,但随后, 我发现django-hCaptcha并不会校验cf turnstile,
因此, 我查看了django-hCaptcha的源码, 得到发现了h-captcha-response和g-captcha-response,
查阅hCaptcha和turnstile的官方文档, 更改了其源码, 在github上发布了我的项目django-turnstile
, 修改了一部分urlencode和response, 并提交到了pypi
我将前期的文章内容删除, 得到了上方的文字
你可以将django-hcaptcha
换为django-turnstile
, 添上turnstile的sitekey和secert, 其他api和django-hcaptcha
相同
pip install django-turnstile
不知道镜像站是否有同步过来, 但我试的阿里云镜像站还没同步过来, 所以最好用python官方站下载 或者, 在pypi (https://pypi.org/project/django-turnstile) 或 github (https://github.com/zmh-program/django-turnstile) 下载并安装
python setup.py install
我相信你已经跟着步骤一步一步来了,而不是直接跳或快速滑到了底部 如果你这么做了,如果你也成功了,我相信你会有不小的收获,许多的快乐,这是做其他事情所无法比拟的,尤其是对于兴趣爱好的喜悦心情 如此普遍的校验码竟还有这么大的学问,我今天介绍的连冰山一角都不如,因为我的时间和章幅原因,就不再过多阐述了。不得不感叹人类的智慧, 感叹网络攻防的乐趣,感叹深度学习与强化学习的深奥。
(行了,我还得写作业呢,写这么多…我看看哈,打了1万多字了,差不多行了)
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=zp1jp55bmyfp