djangoangulardjango-csrfcsrf-token

CSRF Token in Angular 17 using django


I am using django for backend and for POST/GET request I am using this function which is

def player_list(request):
    if request.method == 'GET':
        players = Player.objects.all().values() # get all players as Python dictionaries
        player_list = list(players)
        return JsonResponse(player_list, safe=False)
    elif request.method == 'POST':
        try:
            data = json.loads(request.body) # load JSON data from request
            player = Player(**data) # create a new player instance
            player.full_clean()  # validate the player instance
            player.save() # save the player instance to the database
            return JsonResponse({'message': 'Player created successfully.'}, status=201)
        except json.JSONDecodeError:
            return HttpResponse('Invalid JSON', status=400)
        except ValidationError as e:
            return JsonResponse({'error': e.message_dict}, status=400)
    else:
        return HttpResponse('Invalid HTTP method', status=405)

if I add @csrf_exempt above my function then it fetch the POST the data in database otherwise my Angular apps gives me 403 error. even I have added in app.module.ts

imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    FormsModule,
    HttpClientXsrfModule.withOptions({
      cookieName: 'csrftoken',
      headerName: 'X-CSRFToken'
    })
  ],

and my POST fucntion in service is

 postPlayers(player: Player): Observable<any>
 {
    return this.http.post(this.url, player, { headers: { Accept: 'application/json' }});
 }

I am new so I am not able to figure it out. can anyone help me please?

The data should be store in the database with CSRF token but its not.


Solution

  • step1

    Either on your Angular code use the default csrf header name

    default csrf header name: HTTP_X_CSRFTOKEN

    or

    on django's settings.py set the custom name for csrf header:

    CSRF_HEADER_NAME = 'X-CSRFToken'
    

    reference


    step2

    on django's settings.py

    a. Make sure CSRF_COOKIE_HTTPONLY is set to False

    Default: False

    Whether to use HttpOnly flag on the CSRF cookie. If this is set to True, client-side JavaScript will not be able to access the CSRF cookie.

    reference

    b. Make sure CSRF_USE_SESSIONS is set to False

    Default: False

    Whether to store the CSRF token in the user’s session instead of in a cookie.

    reference


    step3

    in Angular 17, on your app.config.ts file

    Add withXsrfConfiguration to the provideHttpClient call as follows:

    export const appConfig: ApplicationConfig = {
      providers: [
        provideHttpClient(
          withXsrfConfiguration({
            cookieName: 'csrftoken',
            headerName: 'X-CSRFToken',
          }),
        ),
      ]
    };
    

    Reference