为什么我不能在对 Django REST API 的请求中设置 X-CSRFToken?
Why I can't set X-CSRFToken in request to Django REST API?
好吧,我已经尝试解决这个问题两天了,但我无法弄清楚问题出在哪里,您对测试、阅读或解决方案的建议将不胜感激,解释如下:
我正在制作 chrome 扩展以将一些数据添加到 Django REST API,在 POST 请求时将 @csrf_exempt
装饰器添加到视图时它工作正常由 chrome 扩展生成,当 POST
请求来自同一域时,即使我删除了 @csrf_exempt
装饰器(本地服务器),但是当我尝试创建 POST 来自我的扩展程序的请求我收到此服务器错误:Forbidden (CSRF cookie not set.) 但实际上我将 X-CSRFToken
header 添加到我的请求中,我甚至硬编码了令牌,但服务器仍然告诉 CSRF 令牌不存在。
我已经在使用 django-cors-headers-multi 1.2.0 并且 POST 来自外部域的请求在不需要 CSRF 检查时有效。
我查看以下链接:
Django X-CSRFToken have been set but still get 403 forbidden --> 但我没有发出 XML 请求,我应该尝试发出一个吗? (我从来没有做过,我想节省时间所以我现在不想学)
https://pypi.org/project/django-cors-headers-multi/ --> 我已经添加了 CORS_ALLOW_CREDENTIALS = False
因为在我在 chrome 控制台上获得以下消息之前:对预检请求的响应未通过访问控制检查:响应中'Access-Control-Allow-Credentials'header的值为'',当请求的凭证模式为'include'[=24时,必须为'true' =]
这是我认为与解决此问题相关的代码:
前端(扩展代码)
function makeRequest(value, csrf) {
// Send data to server
url = 'http://127.0.0.1:8000/smoke/add/';
let request = new Request(url, {
method: 'POST',
credentials: 'include',
headers: myHeaders,
headers: {
'Content-Type': 'text/plain',
'X-CSRFToken': 'hardCodedToken',
},
body: JSON.stringify({
info: value,
}),
});
return request;
}
chrome.storage.sync.get('token', (csrf) => {
request = makeRequest(contactData, csrf);
console.log(request);
fetch(request) // Error is here
.then((response) => response.json())
.then((data) => {
if (data.error !== undefined) {
alert('Este nombre de contacto ya existe');
} else {
console.log(data.contact);
}
});
});
这是我获得的控制台打印:
服务器代码:
@ensure_csrf_cookie
def add_lead(request):
added = False
if request.method == 'POST':
try:
data = json.loads(request.body)
#creates lead
lead = Lead.objects.create(name=data['info']['name'], nick=data['info']['nick'])
lead.save()
#creates contact from lead
WA_phone = None
try:
WA_phone = data['info']['WApn']
except:
pass
phone = LeadPhone.objects.create(lead=lead, phone=data['info']['phone'], whats_app=WA_phone)
phone.save()
mail = LeadMail.objects.create(lead=lead, mail=data['info']['mail'])
mail.save()
field = LeadField.objects.create(lead=lead, field=data['info']['field'])
field.save()
added = True # shows status to JS fetch function
contact = {
'lead': lead.id,
'name': lead.name,
'nick': lead.nick,
'phone': phone.phone,
'mail': mail.mail,
'field': field.field
}
ids = {
'phone': phone.id,
'mail': mail.id
}
except IntegrityError:
return JsonResponse({'added': added, 'error': 'contacto existente'})
return JsonResponse({'added': added, 'contact': contact, 'ids': ids})
这是我收到以下错误的地方:
禁止(未设置 CSRF cookie。):/smoke/add/
这是我的 settings.py 配置 cors-headers:
CORS_ORIGIN_WHITELIST = ["https://extension.runningdomain.com"]
CORS_ALLOW_HEADERS = (
'x-requested-with',
'content-type',
'accept',
'origin',
'authorization',
'x-csrftoken'
)
CORS_ALLOW_CREDENTIALS = True
感谢大家的支持,抱歉我的英语不好。
@wOxxOm 你的建议再次帮助了我。
对于 chrome 扩展,您无法从内容脚本发出提取请求,当我将提取过程更改为后台脚本时一切正常。
所以解决方案是从后台脚本发出请求。
https://www.chromium.org/Home/chromium-security/extension-content-script-fetches
好吧,我已经尝试解决这个问题两天了,但我无法弄清楚问题出在哪里,您对测试、阅读或解决方案的建议将不胜感激,解释如下:
我正在制作 chrome 扩展以将一些数据添加到 Django REST API,在 POST 请求时将 @csrf_exempt
装饰器添加到视图时它工作正常由 chrome 扩展生成,当 POST
请求来自同一域时,即使我删除了 @csrf_exempt
装饰器(本地服务器),但是当我尝试创建 POST 来自我的扩展程序的请求我收到此服务器错误:Forbidden (CSRF cookie not set.) 但实际上我将 X-CSRFToken
header 添加到我的请求中,我甚至硬编码了令牌,但服务器仍然告诉 CSRF 令牌不存在。
我已经在使用 django-cors-headers-multi 1.2.0 并且 POST 来自外部域的请求在不需要 CSRF 检查时有效。
我查看以下链接:
Django X-CSRFToken have been set but still get 403 forbidden --> 但我没有发出 XML 请求,我应该尝试发出一个吗? (我从来没有做过,我想节省时间所以我现在不想学)
https://pypi.org/project/django-cors-headers-multi/ --> 我已经添加了 CORS_ALLOW_CREDENTIALS = False
因为在我在 chrome 控制台上获得以下消息之前:对预检请求的响应未通过访问控制检查:响应中'Access-Control-Allow-Credentials'header的值为'',当请求的凭证模式为'include'[=24时,必须为'true' =]
这是我认为与解决此问题相关的代码: 前端(扩展代码)
function makeRequest(value, csrf) {
// Send data to server
url = 'http://127.0.0.1:8000/smoke/add/';
let request = new Request(url, {
method: 'POST',
credentials: 'include',
headers: myHeaders,
headers: {
'Content-Type': 'text/plain',
'X-CSRFToken': 'hardCodedToken',
},
body: JSON.stringify({
info: value,
}),
});
return request;
}
chrome.storage.sync.get('token', (csrf) => {
request = makeRequest(contactData, csrf);
console.log(request);
fetch(request) // Error is here
.then((response) => response.json())
.then((data) => {
if (data.error !== undefined) {
alert('Este nombre de contacto ya existe');
} else {
console.log(data.contact);
}
});
});
这是我获得的控制台打印:
服务器代码:
@ensure_csrf_cookie
def add_lead(request):
added = False
if request.method == 'POST':
try:
data = json.loads(request.body)
#creates lead
lead = Lead.objects.create(name=data['info']['name'], nick=data['info']['nick'])
lead.save()
#creates contact from lead
WA_phone = None
try:
WA_phone = data['info']['WApn']
except:
pass
phone = LeadPhone.objects.create(lead=lead, phone=data['info']['phone'], whats_app=WA_phone)
phone.save()
mail = LeadMail.objects.create(lead=lead, mail=data['info']['mail'])
mail.save()
field = LeadField.objects.create(lead=lead, field=data['info']['field'])
field.save()
added = True # shows status to JS fetch function
contact = {
'lead': lead.id,
'name': lead.name,
'nick': lead.nick,
'phone': phone.phone,
'mail': mail.mail,
'field': field.field
}
ids = {
'phone': phone.id,
'mail': mail.id
}
except IntegrityError:
return JsonResponse({'added': added, 'error': 'contacto existente'})
return JsonResponse({'added': added, 'contact': contact, 'ids': ids})
这是我收到以下错误的地方: 禁止(未设置 CSRF cookie。):/smoke/add/
这是我的 settings.py 配置 cors-headers:
CORS_ORIGIN_WHITELIST = ["https://extension.runningdomain.com"]
CORS_ALLOW_HEADERS = (
'x-requested-with',
'content-type',
'accept',
'origin',
'authorization',
'x-csrftoken'
)
CORS_ALLOW_CREDENTIALS = True
感谢大家的支持,抱歉我的英语不好。
@wOxxOm 你的建议再次帮助了我。
对于 chrome 扩展,您无法从内容脚本发出提取请求,当我将提取过程更改为后台脚本时一切正常。
所以解决方案是从后台脚本发出请求。
https://www.chromium.org/Home/chromium-security/extension-content-script-fetches