【问题标题】:Send Angular PUT request to Django using Django CSRF使用 Django CSRF 向 Django 发送 Angular PUT 请求
【发布时间】:2019-12-18 21:54:33
【问题描述】:

我正在尝试使用 put 请求更新 django sqlite 数据库的条目。我收到很多“禁止”和“403”错误。我认为这是因为我找不到从 django 附加 CSRF 令牌的方法。

我在这里看到了一些以前的答案,但它们来自更旧版本的 Angular,我不知道如何编辑它们以使用我的代码。 (说把它们放在我找不到的 module.config() 块中)。

组件 HTML:

<button class="btn btn-warning shadow-sm" (click)="update(project)">Update</button>

组件 TS:

update(project: Project) {
    this.projectService.updateProject(project).subscribe();
}

服务 TS:

updateProject(project: Project) {
    var httpudpdate: any = this.http.put('/ph/projects/'+project.id, project)
    return httpudpdate
}

我希望在 django 中更新条目,但我只是收到错误、禁止和 403。

【问题讨论】:

    标签: django angular csrf put


    【解决方案1】:

    只需将HttpClientXsrfModule 导入您的项目,它将负责读取cookie 并将其作为自定义标头在每个请求中重新发送。

    cookie 和标头名称不是标准,而是约定,因此如果默认名称与后端的名称不匹配,您可以配置它们。

    碰巧,Django 的 cookie 名称和标头名称与 Angular 默认名称不匹配,因此必须像这样导入 HttpClientXsrfModule withOptions

    import { HttpClientModule, HttpClientXsrfModule } from '@angular/common/http';
    
    @NgModule({
        ...
        imports:[..., HttpClientXsrfModule.withOptions({ cookieName: 'csrftoken', headerName: 'X-CSRFToken' }), ...]
        ...
    })
    

    【讨论】:

    • 非常感谢!尚未完全排序,但似乎在正确的轨道上!
    • 如果 Django 使用 XSRF-TOKEN 作为 cookie 名称并使用 X-XSRF-TOKEN 作为标头名称,则模块应该开箱即用。如果没有,则导入HttpClientXsrfModule.withOptions({ cookieName: 'djangoCookieName', headerName: 'djangoHeaderName' }) 而不仅仅是HttpClientXsrfModule
    • 如何检查它使用的默认值?
    • 据此:docs.djangoproject.com/fr/2.2/ref/csrf 标头名称为X-CSRFToken,cookie 名称为csrftoken。您至少可以通过查看浏览器开发工具的网络选项卡来验证 cookie 名称
    • 查看网络选项卡让我更加困惑,因为似乎已经为 put 设置了 cookie,并且它与 get 中的相同。它确实说只允许 GET、POST、HEAD 和 OPTIONS。有没有办法让它允许 PUT,这样我就不会收到禁止的错误?
    【解决方案2】:

    HttpClientXsrfModule 导入您的app.module.ts

    <!-- app.module.ts -->
    import { HttpClientModule, HttpClientXsrfModule } from '@angular/common/http';
    
    imports:[...,HttpClientXsrfModule,...]
    

    HttpXsrfTokenExtractor 注入到您的serviceHttpInterceptor 或您要在其中使用cookie 的文件中。

    constructor(private cookieExtractor:HttpXsrfTokenExtractor){}
    

    获取cookie,例如xsrftoken

    const xsrf: string = this.cookieExtractor.getToken();
    

    【讨论】:

    • 非常感谢!我试图遵循这一点,但无法弄清楚如何在我的代码中实现它?我的服务类中有 2 个方法,1 个返回数据库中的所有“项目”,另一个是尝试更新,如我在原始帖子中所示。我在哪里放置 const 以及如何将其附加到 put 请求?
    • HTTP 请求的标头在哪里添加?
    • 我已经尝试过了,但是更新按钮不再发送放置请求,我只是得到'TypeError:“n is null”'。但这可能只是因为我做错了。任何帮助将不胜感激。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-13
    • 2018-07-20
    • 1970-01-01
    • 2021-01-11
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多