Django 服务器 403(CSRF 令牌丢失或不正确)
Django server 403 (CSRF token missing or incorrect)
我有一个带有 python 命令行客户端的基本 Django 服务器,用于 posting 到此服务。我有一个登录功能和一个 post 功能。即使 CSRF 的 cookie 是从登录功能设置的,当我在登录后尝试访问 post_product 端点时,服务器仍然说禁止。
我已经为此排查了好几天,但一直没有成功。
/api/login/函数:
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth import authenticate, login, logout
from django.http import HttpResponse
@csrf_exempt
def handle_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
if user.is_authenticated:
return HttpResponse(author.name + ' is logged in, Welcome!', status=201, content_type='text/plain')
return HttpResponse(data)
else:
return HttpResponse('disabled account', status=400, content_type='text/plain')
else:
return HttpResponse('invalid login', status=400, content_type='text/plain')
else:
return HttpResponse('request method invalid ' + request.method, status=400, content_type='text/plain')
/api/postproduct/函数:
def post_story(request):
if request.method == 'POST' and request.user.is_authenticated:
# Pull product details from request.
# Validate product details.
# Create model and save.
Python终端客户端
FAILURE_MESSAGE = "The server responded with an unsuccessful code: "
def run():
url ='http://127.0.0.1:8000' # For debugging
logged_in = false
with requests.session() as session:
while True:
command = input("""Enter one of the following commands:
login
post \n""")
# login case.
if command == "login":
url = user_inputs[1]
logged_in = login(session, url)
continue
# post case.
elif command == "post" and logged_in:
post(session, url)
continue
else:
print('incorrect command')
continue
def login(session, url):
username = input("Enter your username: \n")
password = input("Enter your password: \n")
response = session.post(url + "/api/login/", data={'username': username, 'password': password})
# If any response but success notify user.
if response.status_code != 201:
print(FAILURE_MESSAGE + str(response.status_code))
return False
else:
print("Successfully logged in!")
return True
def post(session, url):
# Check session is authenticated
if 'csrftoken' not in session.cookies:
print("Not authenticated, have you logged in to a service?")
return
# Omitted : prompt user for productname, category, price and details.
data = {'productname': productname, 'category': category, 'price': price, 'details': details}
data_json = json.dumps(data)
payload = {'json_payload': data_json}
if not session_is_active():
print("You aren't logged into any services")
return
else:
response = session.post(url + "/api/postproduct/", data=payload)
print(6)
if response.status_code != 201:
print(FAILURE_MESSAGE + str(response.status_code))
return
print("Post was successful")
当我 运行 客户端时,登录工作正常并且在检查时确实设置了 csrf cookie。但是,当我尝试 post 时,服务器以 403 禁止响应。从服务器的输出:
[15/Aug/2019 15:45:23] "POST /api/login/ HTTP/1.1" 201 42
Forbidden (CSRF token missing or incorrect.): /api/postproduct/
Django 的 CSRF 保护要求您 post CSRF cookie 和隐藏在表单字段中的令牌。 For AJAX requests,可以设置一个header代替表单域。
尝试如下操作(未经测试):
headers = {'X-CSRFToken': session.cookies['csrftoken']}
response = session.post(url + "/api/postproduct/", data=payload, headers=headers)
向 Django 后端提交请求时出现错误 = csrf 禁止(CSRF 令牌丢失或不正确。):
在表单中,包含 {% csrf_token %}
,它会生成一个带有 csrf 令牌值的输入标签,
在请求中,让 headers 包含‘X-CSRFTOKEN
headers: {
content_type: 'application/json',
'X-CSRFToken': "{{ csrf_token }}"
},
我有一个带有 python 命令行客户端的基本 Django 服务器,用于 posting 到此服务。我有一个登录功能和一个 post 功能。即使 CSRF 的 cookie 是从登录功能设置的,当我在登录后尝试访问 post_product 端点时,服务器仍然说禁止。
我已经为此排查了好几天,但一直没有成功。
/api/login/函数:
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth import authenticate, login, logout
from django.http import HttpResponse
@csrf_exempt
def handle_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
if user.is_authenticated:
return HttpResponse(author.name + ' is logged in, Welcome!', status=201, content_type='text/plain')
return HttpResponse(data)
else:
return HttpResponse('disabled account', status=400, content_type='text/plain')
else:
return HttpResponse('invalid login', status=400, content_type='text/plain')
else:
return HttpResponse('request method invalid ' + request.method, status=400, content_type='text/plain')
/api/postproduct/函数:
def post_story(request):
if request.method == 'POST' and request.user.is_authenticated:
# Pull product details from request.
# Validate product details.
# Create model and save.
Python终端客户端
FAILURE_MESSAGE = "The server responded with an unsuccessful code: "
def run():
url ='http://127.0.0.1:8000' # For debugging
logged_in = false
with requests.session() as session:
while True:
command = input("""Enter one of the following commands:
login
post \n""")
# login case.
if command == "login":
url = user_inputs[1]
logged_in = login(session, url)
continue
# post case.
elif command == "post" and logged_in:
post(session, url)
continue
else:
print('incorrect command')
continue
def login(session, url):
username = input("Enter your username: \n")
password = input("Enter your password: \n")
response = session.post(url + "/api/login/", data={'username': username, 'password': password})
# If any response but success notify user.
if response.status_code != 201:
print(FAILURE_MESSAGE + str(response.status_code))
return False
else:
print("Successfully logged in!")
return True
def post(session, url):
# Check session is authenticated
if 'csrftoken' not in session.cookies:
print("Not authenticated, have you logged in to a service?")
return
# Omitted : prompt user for productname, category, price and details.
data = {'productname': productname, 'category': category, 'price': price, 'details': details}
data_json = json.dumps(data)
payload = {'json_payload': data_json}
if not session_is_active():
print("You aren't logged into any services")
return
else:
response = session.post(url + "/api/postproduct/", data=payload)
print(6)
if response.status_code != 201:
print(FAILURE_MESSAGE + str(response.status_code))
return
print("Post was successful")
当我 运行 客户端时,登录工作正常并且在检查时确实设置了 csrf cookie。但是,当我尝试 post 时,服务器以 403 禁止响应。从服务器的输出:
[15/Aug/2019 15:45:23] "POST /api/login/ HTTP/1.1" 201 42
Forbidden (CSRF token missing or incorrect.): /api/postproduct/
Django 的 CSRF 保护要求您 post CSRF cookie 和隐藏在表单字段中的令牌。 For AJAX requests,可以设置一个header代替表单域。
尝试如下操作(未经测试):
headers = {'X-CSRFToken': session.cookies['csrftoken']}
response = session.post(url + "/api/postproduct/", data=payload, headers=headers)
向 Django 后端提交请求时出现错误 = csrf 禁止(CSRF 令牌丢失或不正确。):
在表单中,包含 {% csrf_token %}
,它会生成一个带有 csrf 令牌值的输入标签,
在请求中,让 headers 包含‘X-CSRFTOKEN
headers: {
content_type: 'application/json',
'X-CSRFToken': "{{ csrf_token }}"
},