禁止(未设置 CSRF cookie。):/paypal/ |姜戈

Posted

技术标签:

【中文标题】禁止(未设置 CSRF cookie。):/paypal/ |姜戈【英文标题】:Forbidden (CSRF cookie not set.): /paypal/ | Django 【发布时间】:2020-01-16 19:42:12 【问题描述】:

我在使用 django-paypal 时遇到问题,问题发生在付款成功完成后收到 paypal IPN 的那一刻。

错误:

Forbidden (CSRF cookie not set.): /paypal/
[15/Sep/2019 22:53:04] "POST /paypal/ HTTP/1.1" 403 2896
Forbidden (CSRF cookie not set.): /paypal/
[15/Sep/2019 22:53:19] "POST /paypal/ HTTP/1.1" 403 2896
Forbidden (CSRF cookie not set.): /paypal/
[15/Sep/2019 22:53:42] "POST /paypal/ HTTP/1.1" 403 2896
Forbidden (CSRF cookie not set.): /paypal/
[15/Sep/2019 22:54:24] "POST /paypal/ HTTP/1.1" 403 2896
Forbidden (CSRF cookie not set.): /paypal/
[15/Sep/2019 22:55:45] "POST /paypal/ HTTP/1.1" 403 2896

我不知道发生了什么,我开始调查错误但我没有取得多大成就,调查我将文件settings.pyCSRF_COOKIE_SECURE作为True放入,即使这样它也没有用,有什么解决办法吗?


这是付款的代码:

def process_payment(request, pk):
    course = get_object_or_404(Course, pk = pk)
    host = request.get_host()

    paypal_dict = 
        'business': settings.PAYPAL_RECEIVER_EMAIL,
        'item_name': course.title,
        'amount': course.price,
        'currency_code': 'USD',
        'notify_url': 'http://'.format(host, reverse('paypal-ipn')),
        'return_url': 'http://'.format(host, reverse('course:list')),
        'cancel_return': 'http://'.format(host, reverse('payment_cancelled')),
    

    form = PayPalPaymentsForm(initial = paypal_dict)
    return render(request, 'carts/process_payment.html', 'form': form, 'course': course)

更新

给出错误的视图不是我做的,来自负责管理paypal IPN的django-paypal,该视图称为ipn。观点如下:

https://github.com/spookylukey/django-paypal/blob/master/paypal/standard/ipn/views.py

那个视图是notify_url

欲了解更多信息,这是我正在做的指南:https://overiq.com/django-paypal-integration-with-django-paypal/

这些是我的应用程序的 urls.py:

urlpatterns = [
    path('cart/', CartDetailView.as_view(), name = 'cart'),
    path('cart-add/', views.add_course, name = 'add_course'),
    path('process-payment/<int:pk>/', views.process_payment, name='process_payment'),
    path('payment-cancelled/', views.payment_canceled, name='payment_cancelled'),

]

这些是 django-paypal ipn 应用程序的 urls.py

urlpatterns = [
    url(r'^$', views.ipn, name="paypal-ipn"),
]

这将是我的 urlconf:

urlpatterns = [
    path('django-admin/', admin.site.urls),

    # Paths of My Apps
    path('admin/', include(administration_patterns)),
    path('', include('core.urls')),
    path('', include('carts.urls')),
    path('', include(course_patterns)),
    path('paypal/', include('paypal.standard.ipn.urls')),

    # Paths of Auth
    path('accounts/', include('django.contrib.auth.urls')),
    path('accounts/', include('registration.urls')),
]

【问题讨论】:

你运行什么代码来发出这个请求? 我已经用代码更新了我的问题 请使用处理/paypal/ 路径的urls.py 更新您的问题,我将在早上更新我的答案。谢谢 或者你可以链接一个 github 项目,这样会更容易(记得先删除 api 密钥!) 好的,现在更新我的问题,验证,感谢您的帮助! 【参考方案1】:

尝试将 Paypal URL 模式移到顶部,以确保请求实际路由到 django-paypal

urlpatterns = [
    path('django-admin/', admin.site.urls),

    # Paths of My Apps
    path('paypal/', include('paypal.standard.ipn.urls')),
    path('admin/', include(administration_patterns)),
    path('', include('core.urls')),
    path('', include('carts.urls')),
    path('', include(course_patterns)),

    # Paths of Auth
    path('accounts/', include('django.contrib.auth.urls')),
    path('accounts/', include('registration.urls')),
]

您为什么会看到此错误?

然后请求被路由到一个不是csrf_exempt的视图,所以CSRF中间件需要一个CSRF cookie。

由于请求是从 Paypal 服务器发送的,它不包含 CSRF cookie,因此您会收到错误 Forbidden (CSRF cookie not set.)

为什么请求被路由到错误的视图?

模式以深度优先的方式进行匹配,这意味着 Django 在尝试匹配 path('paypal/', include('paypal.standard.ipn.urls')) 之前首先尝试包含在 'core.urls''carts.urls'course_patterns 中的所有模式

其中一个包含的 URL 模式匹配路径 /paypal/,可能类似于 course_patterns 中的 path('&lt;slug&gt;/', course_view)

urlpatterns 列表中将path('paypal/', include('paypal.standard.ipn.urls')), 上移可确保Django 先尝试匹配它。

【讨论】:

谢谢!!那是错误!虽然我不知道为什么......以同样的方式谢谢! 我已经扩展了我的答案以解释您为什么会看到这个特定错误【参考方案2】:

只需在呈现表单的模板上添加csrf token。

<form method="POST" action="/"> % csrf_token %
     form 

</form>

更新

您需要使正在处理/paypal/ csrf 的视图免除。我假设该视图是 paypal 在付款后尝试将用户重定向到的位置:

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def paypal_view(req):
...

更新 2

试试这个:

from django.views.decorators.csrf import csrf_exempt

urlpatterns = [
    url(r'^$', csrf_exempt(views.ipn), name="paypal-ipn"),
]

【讨论】:

我已经做了,那不是问题,问题是视图...那个视图不渲染任何模板,它负责管理paypal IPN ... @JulioCesar 你能显示notify_url 的视图/网址吗?你可能只需要做到csrf_exempt 或者任何视图正在处理/paypal/,这就是你的错误所在。 这里是django-paypal的源代码,这是管理IPN的视图:github.com/spookylukey/django-paypal/blob/master/paypal/… 那个视图是notify_url (ipn)

以上是关于禁止(未设置 CSRF cookie。):/paypal/ |姜戈的主要内容,如果未能解决你的问题,请参考以下文章

Django(DRF)和React - 禁止(未设置CSRF cookie)

从 Vue.js 向 Django 发送 POST/DELETE 请求时禁止(未设置 CSRF cookie。)

Django REST Framework CSRF 失败:未设置 CSRF cookie

Django 1.9 AJAX 表单 CSRF 令牌 403 错误 - “未设置 CSRF cookie”

CSRF cookie 未设置 - 可能被 kubernetes 入口阻止

直接访问登录表单时未设置会话 cookie,导致 CSRF 令牌无效