如何将CSRF令牌添加到来自Django 2.2的Angular 8 post请求

Nas*_*imi 5 python django csrf angular

我有一个带有 Django 后端和角度前端的应用程序。现在,这些相互连接,我可以从 Django 获取数据并在 Angular 中显示。以及向 Django 发送 post 请求。

但问题在于 Django 中的 CSRF 令牌。我在 Django 和请求过程中完全禁用了 CSRF 中间件,但我知道这是不安全的。

执行发布请求的方法。

loadQuestion(id): Observable<any> {
    const body = {'choice': 'teseted with post method'};
    return this.http.post(this.baseUrl + id + '/vote', {headers: this.header, withCredentials: true, });
  }
Run Code Online (Sandbox Code Playgroud)

我根据这个链接做了一些改变。

HttpClientXsrfModule.withConfig({ cookieName: 'csrftoken', headerName: 'X-CSRFToken' })

但我收到这个错误。

app.module.ts:26 Uncaught TypeError: _angular_common_http__WEBPACK_IMPORTED_MODULE_3__.HttpClientXsrfModule.withConfig 不是函数

所以我根据这个链接改变了它

HttpClientXsrfModule.withOptions({ cookieName: 'csrftoken', headerName: 'X-CSRFToken' })

这是我的 Django 返回数据的函数,正如我在禁用 CSRF 中间件时所说的那样工作正常所以我应该修复 CSRF 问题并通过 Angular 请求传递它。

def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=4)
    except (KeyError, Choice.DoesNotExist):
        # Redisplay the question voting form.
        return HttpResponse("You didn't select a choice.")
    else:
        selected_choice.votes += 1
        selected_choice.save()
        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponse(request)
Run Code Online (Sandbox Code Playgroud)

我评论的中间件代码:

'django.middleware.csrf.CsrfViewMiddleware'

错误是 CSRF verification failed. Request aborted.

更新

我使用 CORS Origin,这是我的 Django 配置

CORS_ORIGIN_ALLOW_ALL = True

CSRF_COOKIE_SECURE = False
CSRF_USE_SESSIONS = False

CORS_ORIGIN_ALLOW_ALL = True

CORS_ALLOW_HEADERS = (
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
    'X-CSRFToken',
    'x-csrftoken',
    'X-XSRF-TOKEN',
    'XSRF-TOKEN',
    'csrfmiddlewaretoken',
    'csrftoken',
    'X-CSRF'
)

CORS_ALLOW_CREDENTIALS = True
Run Code Online (Sandbox Code Playgroud)

小智 1

你可以用以下方式包装你的视图csrf_exempt

\n\n
from django.views.decorators.csrf import csrf_exempt\n\n@csrf_exempt\ndef vote():\n...\n
Run Code Online (Sandbox Code Playgroud)\n\n

“如果您\xe2\x80\x99使用AngularJS 1.1.3及更高版本,则\xe2\x80\x99足以使用cookie和标头名称配置$http提供程序:”

\n\n
httpProvider.defaults.xsrfCookieName = \'csrftoken\';\n$httpProvider.defaults.xsrfHeaderName = \'X-CSRFToken\';\n
Run Code Online (Sandbox Code Playgroud)\n