我正在为c#中的某个应用程序构建一个插件,该插件必须与Django rest接口通信。 如您所知,Django使用CSRF令牌来提高安全性。
对Django进行POST / PUT调用时遇到问题。该呼叫将始终返回“ CSRF失败:CSRF令牌丢失或不正确。”。 我在浏览器中测试了该调用(Web界面也可以编辑数据,并且将调用相同的PUT请求),令我惊讶的是,X-CSRFToken标头中使用了一个与cookie中存储的值不同的csrf令牌值。 X-CSRFToken标头是否应该使用新生成的令牌?在此调用之后,将不再使用X-CSRFToken值(旧的csrftoken值仍用于所有后续调用...)。
也许我也阅读了有关csrf令牌的Django文档。即使我认为我了解它是如何工作的,我也不知道为什么要在POST / PUT中使用新令牌。有很多示例在我的C#插件中无法使用。
在做PUT之前我要做什么:
完成上述操作后,所有GET调用均正常运行。 当我尝试执行POST或PUT时会发生问题。 这是我的PUT代码,忽略了json和url的生成,因为这不是问题:
// The _csrftoken used here, is the one I fetch at the beginning
Client().DefaultRequestHeaders.Add("X-CSRFToken", _csrftoken);
// The content is json
var response = Client().PutAsync(url, content).GetAwaiter().GetResult();
// The returned content is: {"detail":"CSRF Failed: CSRF token missing or incorrect."}"
var content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
// 403 is returned
if (response.IsSuccessStatusCode) { ... }
上面的代码具有以下状态:
我试图解决的问题:
有人可以帮助我了解我在做什么错吗?
非常感谢您能给我的帮助。
答案 0 :(得分:0)
所以这里的问题是我们试图在浏览网页的上下文之外使用该API,而纯粹是将其用作执行GET / POST / ..调用的API。当您使用CSRF令牌时,这将不起作用,因为当在html页面中以cookie和元数据的形式浏览时,这些令牌会一起传递。
因此,仅当在浏览上下文中使用API时,才能将具有CSRF令牌的api一起使用。 如果要在该上下文之外使用API,则需要使用其他身份验证形式,例如OAuth2。
要使此功能在没有浏览上下文的情况下有效,您必须为每个POST / PUT / DELETE获取一个html页面,以获取新的CSRF令牌,您必须将其随调用一起传递。 显然,这会带来很多开销,而这并不是您要使用API的方式。
我请API开发人员提供OAuth2身份验证。