如何使用paypal在django中实现csrf?

时间:2016-02-03 15:53:54

标签: django paypal csrf

根据教程https://django-paypal.readthedocs.org/en/stable/standard/ipn.html我尝试将Paypal实现到我的网页。

到目前为止我所拥有的:

views.py

def view_that_asks_for_money(request):
    c = {}
    # What you want the button to do.
    paypal_dict = {
        "business": settings.PAYPAL_RECEIVER_EMAIL,
        "amount": "0.01",
        "item_name": "name of the item",
        "invoice": "unique-invoice-id",
        "notify_url": "xxx/nnnn" + reverse('paypal-ipn'),
        "return_url": "xxx/aaa",
        "cancel_return": "xxx/bbb",
        "custom": "Upgrade all users!",  # Custom command to correlate to some function later (optional)
    }

    # Create the instance.
    form = PayPalPaymentsForm(initial=paypal_dict)
    c.update({"form":form})
    return render_to_response(app/payment.html",
                              c,
                              context_instance=RequestContext(request))


def show_me_the_money(sender, **kwargs):
    ipn_obj = sender
    print("hierkamwsan")
    if ipn_obj.payment_status == ST_PP_COMPLETED:
        # Undertake some action depending upon `ipn_obj`.
        if ipn_obj.custom == "Upgrade all users!":
            print("upgradedUser")
            #Users.objects.update(paid=True)
    else:
        print("UwerNotValid")

valid_ipn_received.connect(show_me_the_money)

urls.py(在应用内):

# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url

urlpatterns = patterns('views',
    url(r'money$', 'view_that_asks_for_money', name='view_that_asks_for_money'),#paypal
    url(r'nnnn$', 'show_me_the_money', name='show_me_the_money')#supposed to be the notify_url
)

urls.py(django-cms中的一般情况):

urlpatterns = i18n_patterns('',
    url(r'^paypal/', include('paypal.standard.ipn.urls')),
    ) + staticfiles_urlpatterns() + urlpatterns  # NOQA

payment.html

<{% extends 'base.html' %}
<!DOCTYPE html>
{% block content %}
<html>
    <head>
        <meta charset="utf-8">
        <title>Paypal-Payment</title>   
    </head>
    <body>h1>Show me the money!</h1>
<!-- writes out the form tag automatically -->
{{ form.render }}
{% csrf_token %}
</body>
</html>
{% endblock %}

调用views.py/payment.html时,可以在paypal-sandbox中付款。当定向回到我的页面时,我得到一个django-debugger错误:

Forbidden (403)

CSRF verification failed. Request aborted.
Help

Reason given for failure:

CSRF token missing or incorrect.


In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. For POST forms, you need to ensure:

    Your browser is accepting cookies.
    The view function uses RequestContext for the template, instead of Context.
    In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
    If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.

You're seeing the help section of this page because you have DEBUG = True in your Django settings file. Change that to False, and only the initial error message will be displayed.

You can customize this page using the CSRF_FAILURE_VIEW setting.

任何人都可以告诉我:

  • 如何正确实现csrf-token
  • 如果正确实施处理paypal与notify_url的响应。我认为视图中的调用“valid_ipn_received.connect(show_me_the_money)”是错误的。但是在哪里做?

编辑(我在发送到浏览器时添加了payment.html表单的来源):

<body>h1>Show me the money!</h1>
<!-- writes out the form tag automatically -->
<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">
    <input id="id_business" name="business" type="hidden" value="mymail@mymail.com" /><input id="id_amount" name="amount" type="hidden" value="0.01" /><input id="id_item_name" name="item_name" type="hidden" value="name of the item" /><input id="id_notify_url" name="notify_url" type="hidden" value="http://xxxxx.ngrok.com/en/mypage/" /><input id="id_cancel_return" name="cancel_return" type="hidden" value="http://xxxxx.ngrok.com/en/accounts/login/" /><input id="id_return_url" name="return" type="hidden" value="http://xxxxx.ngrok.com/de/accounts/login/" /><input id="id_custom" name="custom" type="hidden" value="Upgrade all users!" /><input id="id_invoice" name="invoice" type="hidden" value="unique-invoice-id29" /><input id="id_cmd" name="cmd" type="hidden" value="_xclick" /><input id="id_charset" name="charset" type="hidden" value="utf-8" /><input id="id_currency_code" name="currency_code" type="hidden" value="USD" /><input id="id_no_shipping" name="no_shipping" type="hidden" value="1" />
    <input type="image" src="https://www.sandbox.paypal.com/en_US/i/btn/btn_buynowCC_LG.gif" border="0" name="submit" alt="Buy it Now" />
</form>
<input type='hidden' name='csrfmiddlewaretoken' value='5VDa6VWHZFAD6thEsOIwKxhlWPOlOD62' />
</body>

我期待着你的帮助! 码头

1 个答案:

答案 0 :(得分:0)

我还在苦苦挣扎。在django-paypal的模板中找到以下内容。这是我得到的默认按钮的渲染命令。

    def render(self):
        return mark_safe(u"""<form action="%s" method="post">
    %s 
    <input type="image" src="%s" border="0" name="submit" alt="Buy it Now" />
</form>""" % (self.get_endpoint(), self.as_p(), self.get_image()))

现在我想知道是否可以在这个渲染定义中的某个地方集成csrf_token。 是吗?我在哪里添加它?这真的是解决方案吗?还是有更聪明和优雅的东西?