“详细信息”:“CSRF失败:当从angular 13发送post数据到django连接的数据库时,CCSRF令牌丢失,”

irlmq6kh  于 2022-12-01  发布在  Go
关注(0)|答案(2)|浏览(143)

我需要通过Angular 表将后数据从Angular 表发送到DRF,但出现错误
我查了几乎所有的答案可在互联网上,但没有找到和有用的答案。

"detail": "CSRF Failed: CSRF token missing."

//发布逻辑源.服务.ts

import { Injectable } from '@angular/core';
import { sources } from './sources';
import { HttpClient } from '@angular/common/http';
import { Observable , of, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
import { HttpHeaders } from '@angular/common/http';

const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type':  'application/json',
//     Authorization: 'my-auth-token',
    cookieName: 'csrftoken',
    headerName:  'X-CSRFToken',
//     X-CSRFToken: 'sjd8q2x8hgjkvs1GJcOOcgnVGEkdP8f02shB',
//     headerName: 'X-CSRFToken',
//      headerName: ,
  })
};

@Injectable({
  providedIn: 'root'
})
export class SourcesService {
API_URL = 'http://127.0.0.1:8000/sourceapi.api';
  constructor(private http: HttpClient) { }

     /** GET sources from the server */
    Sources() :  Observable<sources[]> {
      return this.http.get<sources[]>(this.API_URL);
    }
      /** POST: add a new source to the server */
//       addSource(data: object) : Observable<object>{
//         return this.http.post<object>(this.API_URL,data, httpOptions);
//       }

addSource(source : sources[]): Observable<sources[]>{
  return this.http.post<sources[]> (this.API_URL, source, httpOptions);
 //console.log(user);
  }
  }

//add-source.component.ts

import { Component, OnInit } from '@angular/core';
import { sources } from '../sources';
import { SourcesService } from '../sources.service';
import { FormGroup, FormControl, ReactiveFormsModule} from '@angular/forms';

@Component({
  selector: 'app-add-source',
  templateUrl: './add-source.component.html',
  styleUrls: ['./add-source.component.css']
})
export class AddSourceComponent implements OnInit {
   // a form for entering and validating data
   sourceForm = new FormGroup({
    name : new FormControl(),
    url : new FormControl(),
    client : new FormControl(),
  });
  constructor(private sourcesService: SourcesService) { }

  ngOnInit(): void {
  }

  sourceData_post: any;
  saveSource(){
    if(this.validate_form()){
      this.sourceData_post = this.sourceForm.value;
      this.sourcesService.addSource(this.sourceData_post).subscribe((source)=>{
      alert('source added');
      });
      }

      else{
      alert('please fill from correctly');
      }
  }
  validate_form(){
    const formData = this.sourceForm.value;
    if(formData.name == null){
      return false;
      }else if(formData.url == null){
      return false;
      }else{
      return true;
      }
      }

}

//添加源代码.组件. html

<div class="bread-crumb">
    <div>    <span>Add Source</span>   </div>
</div>
<div class="container flex">
        <div class="form">
            <form action="" [formGroup]="sourceForm" (ngSubmit)="saveSource()">

                <table>
                    <tr>
                        <td>Source Name:</td>
                        <td>
                            <input class="input" type="text" formControlName="name">
                        </td>
                    </tr>
                    <tr>
                        <td>Source URL:</td>
                        <td>
                            <input class="input" type="text" formControlName="url">
                        </td>
                    </tr>

                     <tr>
                        <td>Source client:</td>
                        <td>
                            <input class="input" type="text" formControlName="client">
                        </td>
                    </tr>
                    <tr>
                        <td colspan="2">
                            <div class="center">
                                <button type="submit">submit</button>
                            </div>
                        </td>
                    </tr>
                </table>
            </form>
        </div>
</div>

我试过了

imports: [
  BrowserModule,
  AppRoutingModule,
  HttpClientModule,
  Ng2SearchPipeModule,
  FormsModule,
  ReactiveFormsModule,
  HttpClientXsrfModule,
  HttpClientXsrfModule.withOptions({
    cookieName: 'XSRF-TOKEN',
    headerName: 'X-XSRF-TOKEN',
    })

但于事无补
注:-这是角13

iq0todco

iq0todco1#

  • (部分答案)*

您收到此错误消息是因为默认情况下激活了CSRF保护,并且您没有发送CSRF令牌。
在第一个GET请求中,服务器在cookie中向您发送CSRF令牌,您必须在每个请求中将其作为cookie和请求头发送回。服务器将检查cookie中的CSRF值是否与头中的CSRF值匹配。
在每次请求时重复这一点可能会很乏味,所以Angular有一个内置的模块:您在此处配置的HttpClientXsrfModule

HttpClientXsrfModule.withOptions({
  cookieName: 'XSRF-TOKEN',
  headerName: 'X-XSRF-TOKEN',
})

一个问题是,您可以通过在此处手动再次设置标头来覆盖此行为:

const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type':  'application/json',
    cookieName: 'csrftoken',
    headerName:  'X-CSRFToken',
  })
};
[...]

addSource(source : sources[]): Observable<sources[]>{
  return this.http.post<sources[]> (this.API_URL, source, httpOptions);

你不需要那个。就这样吧:

addSource(source : sources[]): Observable<sources[]>{
  return this.http.post<sources[]> (this.API_URL, source);

另一个问题是CSRF头/cookie的名称不是标准的。它可以是CSRFXSRF或任何您想要的名称。当然,如果您将其作为CSRF发送,而服务器期望它作为XSRF,则不会检测到它。
从问题的评论中可以看出,服务器向您发送了
设置Cookie:csrftoken= sjd 8 q2 xsdfgfhjgfnVGEkdP 8 f02 shB
所以我们可以确定cookie名称是csrftoken。所以在HttpClientXsrfModule的配置中应该是相同的。您可以这样尝试吗

HttpClientXsrfModule.withOptions({
  cookieName: 'csrftoken', // << This one is certain
  headerName: 'X-XSRF-TOKEN', // << For this one, I don't know yet
})

你能用headerName的不同值来尝试这个吗?最好也用csrftoken?头文件名称和cookie名称通常是相同的。
更新:
根据Django文档,默认的CSRF头文件名是HTTP_X_CSRFTOKEN

HttpClientXsrfModule.withOptions({
  cookieName: 'csrftoken',
  headerName: 'HTTP_X_CSRFTOKEN',
})
5jvtdoz2

5jvtdoz22#

您需要在www.example.com中免除csrfviews.py

from django.views.decorators.csrf import csrf_exempt

然后再

@csrf_exempt
def index(request):
pass

相关问题