使用 Django @csrf_exempt,request.session 总是空的
With Django @csrf_exempt, request.session is always empty
我被困在 django 中,如果有人能帮助我,我将不胜感激。
我需要一个第三方的入口点 API。所以我创建了一个视图并用 @csrf_exempt
装饰它
现在的问题是我无法访问我之前设置的任何会话变量。
编辑 - 我设置了多个会话变量,如用户电子邮件,以了解用户是否已经登录。我能够在调用第 3 方之前使用该会话 API。当第 3 方 API 发送响应时,他们不会发送 CSRF 令牌,因此我已将该视图从 csrf 中排除。收到有效回复后,我想更新我的数据库。为此,我需要知道我丢失的用户的电子邮件 ID,因为我不再有会话变量。
ppConfirmPaymentProcess
是另一个函数,处理由第 3 方 API 发送的 POST 数据。
一切正常,csrf_exempt 也正常,但我无法 request.session["foo"]
处理此请求。有人可以帮忙吗?
@csrf_exempt
def ppConfirmPayment(request):
print(request.session, "=======================================")
for key, value in request.session.items():
print('{} => {}'.format(key, value))
return ppConfirmPaymentProcess(request)
第 3 方 API 可能不是作为登录用户发送响应,当然也不是作为发起交易的用户。
您必须跟踪您向 API 发出的请求以及他们与哪个用户关联,可能在数据库中。当您从 API 获得响应时,您需要将其与那些记录进行匹配,加载相关用户的信息并进行适当的更新。
来自第 3 方的响应 API 与用户的会话完全分开;这意味着它可能会在单独的线程、进程甚至服务器中处理(取决于您的站点的设置方式),因此您需要使用一些跨越这些边界的机制来让用户了解付款结果(这意味着数据库或您为此设置的其他内容)。
request.session 将永远为空,因为它只能由您的系统初始化,一旦连接关闭,会话就会被销毁。对于新连接,设置新会话。由于您的 API 端点由第三方 API 直接触发,而没有触发任何其他端点,因此第三方无法设置会话。因此,request.session 为空。
尝试将信息存储在 request.POST
而不是 request.session 中,这是从第三方获取信息的最佳方式。
查看文档:https://docs.djangoproject.com/en/3.0/topics/http/sessions/
Django 存储标记为会话密钥的会话数据,如下所示:
{"session_key":sdfkjdsbks, "user_email":"abc@df.com"}
在存储用户电子邮件时打印并复制 request.session.session_key 并检查您是否再次在视图中获得相同的 session_key。
如果没有,那么您可以使用复制的会话密钥在视图中强制加载之前的会话:
from importlib import import_module
from django.conf import settings
@csrf_exempt
def ppConfirmPayment(request):
engine = import_module(settings.SESSION_ENGINE)
# copy the old_session_key value from request when you saved user email
request.session = engine.SessionStore(old_session_key)
print(request.session, "=======================================")
for key, value in request.session.items():
print('{} => {}'.format(key, value))
return ppConfirmPaymentProcess(request)
如果这有效,那么您可以将 session_key 发送给第 3 方 API 并请求他们在后续调用中发送 cookie 或数据中的相同会话密钥。并捕获会话密钥并在您的视图中强制加载会话。
我使用 Django 本身解决了它。不操纵会话 ID 或与数据库交互。
Step1: 调用第3方api
@login_required
def thirdPartyAPICall(request):
#do some stuff and send a request to 3rd party
Step2: 在视图中接收来自第3方的回调。请注意我如何放置 csrf_exempt
而不是 login_required
以便第 3 方可以在没有 CSRF 令牌和会话的情况下向我的应用程序发送请求。这就像他们进入我的应用程序的入口点。
在此 callBackView
中执行一些操作并检查这是否确实是来自第 3 方的有效响应或是否有人试图入侵您的系统。
例如。检查 CHECKSUM
或 TXNID
等,然后创建响应字典并在我的应用程序中使用 HttpResponseRedirect
将另一个 HTTP 响应发送到另一个资源,然后我将相关的 GET 参数传递给它。
这个特定的步骤恢复了我以前的会话,现在我有来自第 3 方的相关数据来处理我发送给他们的请求,我也在请求中得到了我的 session
。
@csrf_exempt
def callBackView(request):
if request.POST["CHECKSUM"] == myCalCulatedCheckSum:
foo = True
else:
foo = False
return HttpResponseRedirect("TEST.HTML" +"/" + str(foo))
我最喜欢这种方法,因为正如我之前提到的,我们不需要存储会话,Django 为我们做了。
我被困在 django 中,如果有人能帮助我,我将不胜感激。
我需要一个第三方的入口点 API。所以我创建了一个视图并用 @csrf_exempt
装饰它现在的问题是我无法访问我之前设置的任何会话变量。 编辑 - 我设置了多个会话变量,如用户电子邮件,以了解用户是否已经登录。我能够在调用第 3 方之前使用该会话 API。当第 3 方 API 发送响应时,他们不会发送 CSRF 令牌,因此我已将该视图从 csrf 中排除。收到有效回复后,我想更新我的数据库。为此,我需要知道我丢失的用户的电子邮件 ID,因为我不再有会话变量。
ppConfirmPaymentProcess
是另一个函数,处理由第 3 方 API 发送的 POST 数据。
一切正常,csrf_exempt 也正常,但我无法 request.session["foo"]
处理此请求。有人可以帮忙吗?
@csrf_exempt
def ppConfirmPayment(request):
print(request.session, "=======================================")
for key, value in request.session.items():
print('{} => {}'.format(key, value))
return ppConfirmPaymentProcess(request)
第 3 方 API 可能不是作为登录用户发送响应,当然也不是作为发起交易的用户。
您必须跟踪您向 API 发出的请求以及他们与哪个用户关联,可能在数据库中。当您从 API 获得响应时,您需要将其与那些记录进行匹配,加载相关用户的信息并进行适当的更新。
来自第 3 方的响应 API 与用户的会话完全分开;这意味着它可能会在单独的线程、进程甚至服务器中处理(取决于您的站点的设置方式),因此您需要使用一些跨越这些边界的机制来让用户了解付款结果(这意味着数据库或您为此设置的其他内容)。
request.session 将永远为空,因为它只能由您的系统初始化,一旦连接关闭,会话就会被销毁。对于新连接,设置新会话。由于您的 API 端点由第三方 API 直接触发,而没有触发任何其他端点,因此第三方无法设置会话。因此,request.session 为空。
尝试将信息存储在 request.POST
而不是 request.session 中,这是从第三方获取信息的最佳方式。
查看文档:https://docs.djangoproject.com/en/3.0/topics/http/sessions/
Django 存储标记为会话密钥的会话数据,如下所示:
{"session_key":sdfkjdsbks, "user_email":"abc@df.com"}
在存储用户电子邮件时打印并复制 request.session.session_key 并检查您是否再次在视图中获得相同的 session_key。
如果没有,那么您可以使用复制的会话密钥在视图中强制加载之前的会话:
from importlib import import_module
from django.conf import settings
@csrf_exempt
def ppConfirmPayment(request):
engine = import_module(settings.SESSION_ENGINE)
# copy the old_session_key value from request when you saved user email
request.session = engine.SessionStore(old_session_key)
print(request.session, "=======================================")
for key, value in request.session.items():
print('{} => {}'.format(key, value))
return ppConfirmPaymentProcess(request)
如果这有效,那么您可以将 session_key 发送给第 3 方 API 并请求他们在后续调用中发送 cookie 或数据中的相同会话密钥。并捕获会话密钥并在您的视图中强制加载会话。
我使用 Django 本身解决了它。不操纵会话 ID 或与数据库交互。
Step1: 调用第3方api
@login_required
def thirdPartyAPICall(request):
#do some stuff and send a request to 3rd party
Step2: 在视图中接收来自第3方的回调。请注意我如何放置 csrf_exempt
而不是 login_required
以便第 3 方可以在没有 CSRF 令牌和会话的情况下向我的应用程序发送请求。这就像他们进入我的应用程序的入口点。
在此 callBackView
中执行一些操作并检查这是否确实是来自第 3 方的有效响应或是否有人试图入侵您的系统。
例如。检查 CHECKSUM
或 TXNID
等,然后创建响应字典并在我的应用程序中使用 HttpResponseRedirect
将另一个 HTTP 响应发送到另一个资源,然后我将相关的 GET 参数传递给它。
这个特定的步骤恢复了我以前的会话,现在我有来自第 3 方的相关数据来处理我发送给他们的请求,我也在请求中得到了我的 session
。
@csrf_exempt
def callBackView(request):
if request.POST["CHECKSUM"] == myCalCulatedCheckSum:
foo = True
else:
foo = False
return HttpResponseRedirect("TEST.HTML" +"/" + str(foo))
我最喜欢这种方法,因为正如我之前提到的,我们不需要存储会话,Django 为我们做了。