<p><strong>为什么会发生这种错误?</strong></p>
<p>这是因为DRF使用了默认的<code>SessionAuthentication</code>方案。DRF的<code>SessionAuthentication</code>使用Django的会话框架进行身份验证,这需要检查CSRF。</p>
<p>当您没有在视图/视图集中定义任何<code>authentication_classes</code>时,DRF使用此身份验证类作为默认类。</p>
<pre><code>'DEFAULT_AUTHENTICATION_CLASSES'= (
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication'
),
</code></pre>
<p>由于DRF需要对同一视图同时支持基于会话和非基于会话的身份验证,因此它只对经过身份验证的用户执行CSRF检查。这意味着只有经过身份验证的请求才需要CSRF令牌,并且匿名请求可以在没有CSRF令牌的情况下发送。</p>
<p>如果将AJAX样式的API用于SessionAuthentication,则需要为任何“不安全”HTTP方法调用(例如<code>PUT, PATCH, POST or DELETE</code>请求)包含有效的CSRF令牌。</p>
<p><strong>那该怎么办?</strong></p>
<p>现在要禁用csrf检查,可以创建一个自定义身份验证类<code>CsrfExemptSessionAuthentication</code>,该类扩展自默认的<code>SessionAuthentication</code>类。在这个身份验证类中,我们将重写在实际的<code>SessionAuthentication</code>内部发生的<code>enforce_csrf()</code>检查。</p>
<pre><code>from rest_framework.authentication import SessionAuthentication, BasicAuthentication
class CsrfExemptSessionAuthentication(SessionAuthentication):
def enforce_csrf(self, request):
return # To not perform the csrf check previously happening
</code></pre>
<p>在您的视图中,您可以将<code>authentication_classes</code>定义为:</p>
<pre><code>authentication_classes = (CsrfExemptSessionAuthentication, BasicAuthentication)
</code></pre>
<p>这将处理csrf错误。</p>