带有 Google Recaptcha v3 的 Django 联系表

Posted

技术标签:

【中文标题】带有 Google Recaptcha v3 的 Django 联系表【英文标题】:Django Contact Form With Google Recaptcha v3 【发布时间】:2020-02-16 21:38:21 【问题描述】:

我想将 Google Recaptcha v3 实施到一个有效的 Django 联系表单中。

我尝试按照这些教程进行操作:

https://simpleisbetterthancomplex.com/tutorial/2017/02/21/how-to-add-recaptcha-to-django-site.html

https://foxrow.com/using-recaptcha-v3-with-django

https://medium.com/@mihfazhillah/how-to-implement-google-recaptcha-v3-on-your-django-app-3e4cc5b65013

但是没有运气试图弄清楚。有人可以帮帮我吗?

Settings.py:

GOOGLE_RECAPTCHA_SECRET_KEY = '<KEY>'

HTML:

<script>
    grecaptcha.ready(function() 
        grecaptcha.execute('<SITE_KEY>', action: 'contact')
        .then(function(token) 
            document.getElementById("form").appendChild(document.CreateElement(`<input type="hidden" name="g-recaptcha-response" value=$token`);
        );
    );
</script>

<form role="form" action="" method="post">
    % csrf_token %
     form.as_p 

    <script src='https://www.google.com/recaptcha/api.js?render=<SITE_KEY>'></script>
    <div class="g-recaptcha" data-sitekey="<SITE_KEY>"></div>

    <button type="submit">Submit</button>
</form>

Views.py:

def contact(request):
    form_class = ContactForm

    # new logic!
    if request.method == 'POST':
        form = form_class(data=request.POST)

        if form.is_valid():

            contact_name = request.POST.get(
                'contact_name'
            , '')
            contact_email = request.POST.get(
                'contact_email'
            , '')
            form_content = request.POST.get('content', '')

            # Email the profile with the
            # contact information
            template = get_template('contact_template.txt')
            context = 
                'contact_name': contact_name,
                'contact_email': contact_email,
                'form_content': form_content,
            
            content = template.render(context)

            email = EmailMessage(
                "New contact form submission",
                content,
                "Your website" +'',
                ['GMAIL_ADDRESS'],
                headers = 'Reply-To': contact_email 
            )
            email.send()
            messages.info(request, "Success")

    return render(request, 'contact.html', 
        'form': form_class,
    )

Forms.py:

from django import forms

class ContactForm(forms.Form):
    contact_name = forms.CharField(required=True)
    contact_email = forms.EmailField(required=True)
    content = forms.CharField(
        required=True,
        widget=forms.Textarea
    )

    # the new bit we're adding
    def __init__(self, *args, **kwargs):
        super(ContactForm, self).__init__(*args, **kwargs)
        self.fields['contact_name'].label = "Name:"
        self.fields['contact_email'].label = "Email:"
        self.fields['content'].label = "Message:"

【问题讨论】:

您当前的代码有什么问题?您能描述一下您的代码当前正在做什么(错误、意外行为等)吗? @dirkgroten 当前代码正在工作,它在提交表单时发送电子邮件。 “受 reCAPTCHA 保护”使用 html 显示在右下方。目前,views.py 中没有使用 recaptcha 逻辑,所以我需要一些指导。当我尝试按照我发布的一些教程进行操作时,我通常会收到“无效的 reCAPTCHA。请重试” 您在 POST 请求中提交了 g-recaptcha-response(值是令牌)。您需要从您的视图中将其提交给 Google API 以验证令牌是否有效并接收score。然后,一旦你有了分数,你就可以决定如何继续(例如分数 > 0.5 可以发送电子邮件,分数 Here's the request你应该提交。 @dirkgroten 请使用上面的教程查看 views.py 的 pastebin 以及更新后的 views.py -> pastebin.com/7BVVupR4 我收到以下消息:无效的 reCAPTCHA。请再试一次。成功 向我们展示result(第 20 行),错误消息是您的代码中的内容,但不是 Google 发回的内容。这将有助于查看实际响应。 【参考方案1】:

我今天遇到了同样的问题。 看来 javascript sn-p 不正确:

    您的元素需要一个 ID。 (我的现在是“cform”。) CreateElement 不存在,“c”为小写。 我无法创建具有属性的元素,我必须分几步完成。

我通常不使用 javascript 编写代码,因此我不知道最佳实践,但以下是对我有用的方法:

<script src='https://www.google.com/recaptcha/api.js?render=<KEY>'></script>
<script>
    grecaptcha.ready(function() 
        grecaptcha.execute(<KEY>, action: 'contact')
        .then(function(token) 
            ginput = document.createElement('input');
            ginput.type = "hidden";
            ginput.name = "g-recaptcha-response";
            ginput.value = token;
            document.getElementById("cform").appendChild(ginput);
        );
    );
</script>

【讨论】:

使用您的代码,我在控制台中收到“ReferenceError: grecaptcha is not defined”。不幸的是,实现您的代码不起作用。这是我的代码 -> pastebin.com/BWNU1WHk 你需要把这段代码放在之后从谷歌加载recaptcha脚本。 确实如此。为了清楚起见,我将此行添加到我的答案中。 是的,我相信确实如此。我现在在 recaptcha 管理页面上收到请求,并且我的表单没有产生错误。唯一的事情是控制台正在显示一些奇怪的东西,正如我在上面对 dirkgroten 提到的那样,并且也希望得到一些帮助。否则,我要感谢 ppouchin 和 dirkgroten 的所有帮助:)。我会留下这个问题,以便它可以帮助有相同类型问题的其他人。

以上是关于带有 Google Recaptcha v3 的 Django 联系表的主要内容,如果未能解决你的问题,请参考以下文章

如何解决 Google v3 reCaptcha 超时?

Google Recaptcha v3 示例演示

使用 ng-recaptcha 将 Google reCaptcha v3 集成到 Angular 应用程序中

Google 的 reCAPTCHA v3 的工作原理

测试新的Google reCAPTCHA v3

带有 reCAPTCHA v3 的角反应形式