You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django的HTML表单中集成reCAPTCHA V3?问题排查

Django reCAPTCHA v3 集成问题排查与修复

问题概述

在Django项目中完成reCAPTCHA公私密钥配置,表单类中添加ReCaptchaField后,前端模板渲染验证码字段失败,尝试JS集成但在Django模板中实现逻辑不清晰,需排查前后端问题。

代码中的显性错误

前端模板拼写失误

create.html中验证码字段渲染代码写成了{{ form.catpcha }},正确拼写应为{{ form.captcha }}——这是导致字段无法渲染的直接原因。

前端排查与修复

  1. 引入reCAPTCHA v3核心脚本
    reCAPTCHA v3为隐形验证机制,必须引入官方脚本才能正常工作。在模板的<head>或表单所在的<body>末尾添加:

    <script src="https://www.google.com/recaptcha/api.js?render={{ RECAPTCHA_PUBLIC_KEY }}"></script>
    

    注:需在视图中将RECAPTCHA_PUBLIC_KEY传入模板上下文,或确保模板可直接访问settings变量(可通过django.template.context_processors.settings启用)。

  2. 添加表单提交的JS逻辑
    v3需要在表单提交前获取验证令牌,并将其作为隐藏字段提交。在模板中补充脚本:

    <script>
    document.getElementById('create-form').addEventListener('submit', function(e) {
        e.preventDefault();
        grecaptcha.execute('{{ RECAPTCHA_PUBLIC_KEY }}', {action: 'register'}).then(function(token) {
            // 创建隐藏字段存储令牌
            let tokenInput = document.createElement('input');
            tokenInput.type = 'hidden';
            tokenInput.name = 'g-recaptcha-response';
            tokenInput.value = token;
            document.getElementById('create-form').appendChild(tokenInput);
            // 提交表单
            this.submit();
        }.bind(this));
    });
    </script>
    
  3. 验证字段渲染
    修正拼写错误后,{{ form.captcha }}会生成reCAPTCHA所需的隐藏字段或标记,v3无需显示控件,确保字段能正常生成即可。

后端排查与修复

  1. 依赖与配置检查
    确保已安装django-recaptcha包,并将captcha添加到INSTALLED_APPS:

    INSTALLED_APPS = [
        # ... 其他应用
        'captcha',
    ]
    
  2. 表单类优化
    使用django-recaptcha的ReCaptchaField时,无需手动指定公私密钥(settings中已配置即可),且v3的widget会自动处理验证逻辑,无需额外配置密钥参数:

    class createNewAccountForm(forms.Form):
        name = forms.CharField(required=True, validators=[validate_alphanumericplus])
        email = forms.CharField(required=True)
        password = SetPasswordField(label='Password', required=True)
        captcha = ReCaptchaField(
            widget=ReCaptchaV3(
                attrs={
                    'required_score': 0.85,
                    'action': 'register', # 需与前端JS中的action参数一致
                }
            )
        )
    
  3. 视图类修复

    • 无需在form_valid中手动调用verify,ReCaptchaField会在表单验证阶段自动完成校验
    • return self.form_invalid写法错误,必须传递form参数,正确写法为return self.form_invalid(form)
      优化后的视图代码:
    class createNewAccountView(FormView):
        form_class = createNewAccountForm
        template_name = 'account/create.html'
    
        def form_valid(self, form):
            # 表单已通过captcha验证,直接处理用户创建逻辑
            print("form is valid, creating user")
            print(form.cleaned_data)
            name = form.cleaned_data['name']
            email = form.cleaned_data['email']
            password = form.cleaned_data['password']
            next = form.data.get('next', None)
            # ... 补充用户创建及后续逻辑
            return super().form_valid(form) # 调用父类方法完成默认跳转
    

reCAPTCHA v3 核心集成要点(翻译自官方文档)

reCAPTCHA v3是无干扰式验证方案,无需用户手动交互,通过分析用户页面行为生成0-1之间的分数:

  • 分数越接近1,代表用户为真人的概率越高;分数越接近0,代表越可能是机器人
  • 集成需引入官方脚本,通过grecaptcha.execute获取验证令牌
  • 后端使用私钥向谷歌验证API发起请求,校验令牌有效性及分数
  • 可根据业务需求设置最低分数阈值,拦截高风险请求

内容的提问来源于stack exchange,提问作者Bartosz Tiedemann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 12:47:23