Unable to solve WARNING:django.security.csrf:Forbidden (CSRF cookie not set.)

Hi. I’m new to Django and I’m using a nextjs frontend, which I’m also new to. I am trying to send an image to the django backend but I’m getting a CSRF cookie not set error with a 403.
here’s my nextjs axios call

export async function POST(req: Request) {

  const { imageData } = req.body; 
  console.log("we're are /capture post, trial 2")
  try {

    // Fetch CSRF token from your Django backend
    const csrfResponse = await axios.get('http://localhost:8000/souci/api/get-csrf-token/');
    const csrfToken = csrfResponse.data.csrf_token;

    console.log("cookies!!!")
    console.log(csrfToken)

    axios.defaults.xsrfHeaderName = 'X-CSRFToken';

    //Django backend
    const response = await axios.post(
      'http://localhost:8000/souci/capture/', 
      { imageData },
      {
        headers: {
          'X-CSRFToken': csrfToken,
          'CSRF-Token': csrfToken,
        },
        withCredentials: true
      }
    );

    return NextResponse.json({response});
  } catch (error) {
    console.error('Error sending image data to Django:', error);
    return NextResponse.json({ success: false, error: 'Failed to send image data to Django' });
  }
}

here’s my django backend

def get_csrf_token(request):
    csrf_token = get_token(request)
    return JsonResponse({'csrf_token': csrf_token})

#@csrf_exempt
def capture(request):
    print("this is the request", request)
    if request.method == 'POST':
        if 'webimg' in request.POST:
            image_data = request.POST['webimg'].split(',')[1]
            image_data = base64.b64decode(image_data)

            # Save the image data to model
            time = datetime.datetime.today().strftime('%s')
            image_name = time+'.jpg'
            image_obj = Image.objects.create(title=image_name)
            image_obj.image.save(image_name, ContentFile(image_data))
            
            return JsonResponse({'success': True, 'redirect_url': '/souci/show/'})
        else:
            return JsonResponse({'success': False, 'error': 'No image data found'})
    return render(request, 'souci/capture.html')

I have cors headers installed on django. and my cors allowed origins allows the nextjs. Please need some help with this

Please post your CSRF and CORS-related settings.

from settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    "souci",
    "corsheaders",
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',

]

CORS_ALLOW_CREDENTIALS = True

CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000",
    "http://127.0.0.1:3000"
]

What does the view for this url look like?
(Reason for asking: See How to use Django’s CSRF protection | Django documentation | Django)

it is the get_csrf_token function in my django backend. I get the csrf token from django and then insert it into the header of my POST request

Please post the code for that view.

from django.middleware.csrf import get_token

def get_csrf_token(request):
    csrf_token = get_token(request)
    return JsonResponse({'csrf_token': csrf_token})

The error message is saying that the cookie is not present, not that the token is missing. Try adding the ensure_csrf_cookie decorator to this view.

the error still persists… this is what I get in my nextjs console… (apologies if it’s too long)

Error sending image data to Django: AxiosError: Request failed with status code 403
    at settle (webpack-internal:///(rsc)/./node_modules/axios/lib/core/settle.js:21:16)
    at IncomingMessage.handleStreamEnd (webpack-internal:///(rsc)/./node_modules/axios/lib/adapters/http.js:513:81)
    at IncomingMessage.emit (node:events:526:35)
    at endReadableNT (node:internal/streams/readable:1589:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
    at Axios.request (webpack-internal:///(rsc)/./node_modules/axios/lib/core/Axios.js:50:49)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async POST (webpack-internal:///(rsc)/./src/app/api/capture/route.ts:21:26)
    at async /Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/compiled/next-server/app-route.runtime.dev.js:6:63809
    at async eU.execute (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/compiled/next-server/app-route.runtime.dev.js:6:53964)
    at async eU.handle (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/compiled/next-server/app-route.runtime.dev.js:6:65062)
    at async doRender (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/base-server.js:1333:42)
    at async cacheEntry.responseCache.get.routeKind (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/base-server.js:1555:28)
    at async DevServer.renderToResponseWithComponentsImpl (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/base-server.js:1463:28)
    at async DevServer.renderPageComponent (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/base-server.js:1856:24)
    at async DevServer.renderToResponseImpl (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/base-server.js:1894:32)
    at async DevServer.pipeImpl (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/base-server.js:911:25)
    at async NextNodeServer.handleCatchallRenderRequest (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/next-server.js:271:17)
    at async DevServer.handleRequestImpl (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/base-server.js:807:17)
    at async /Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/dev/next-dev-server.js:331:20
    at async Span.traceAsyncFn (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/trace/trace.js:151:20)
    at async DevServer.handleRequest (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/dev/next-dev-server.js:328:24)
    at async invokeRender (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/lib/router-server.js:163:21)
    at async handleRequest (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/lib/router-server.js:342:24)
    at async requestHandlerImpl (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/lib/router-server.js:366:13)
    at async Server.requestListener (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/lib/start-server.js:140:13) {
  code: 'ERR_BAD_REQUEST',
  config: {
    transitional: {
      silentJSONParsing: true,
      forcedJSONParsing: true,
      clarifyTimeoutError: false
    },
    adapter: [ 'xhr', 'http' ],
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-CSRFToken',
    maxContentLength: -1,
    maxBodyLength: -1,
    env: { FormData: [Function], Blob: [class Blob] },
    validateStatus: [Function: validateStatus],
    headers: Object [AxiosHeaders] {
      Accept: 'application/json, text/plain, */*',
      'Content-Type': 'application/json',
      'X-CSRFToken': 'pidNq708bHWYkM5HiIV5RsqFJGNKYogsuvkeFxVWtCmkgtaUvOFfzerSyx7lNh0h',
      'CSRF-Token': 'pidNq708bHWYkM5HiIV5RsqFJGNKYogsuvkeFxVWtCmkgtaUvOFfzerSyx7lNh0h',
      'User-Agent': 'axios/1.6.7',
      'Content-Length': '2',
      'Accept-Encoding': 'gzip, compress, deflate, br'
    },
    withCredentials: true,
    method: 'post',
    url: 'http://localhost:8000/souci/capture/',
    data: '{}'
  },
  request: <ref *1> ClientRequest {
    _events: [Object: null prototype] {
      abort: [Function (anonymous)],
      aborted: [Function (anonymous)],
      connect: [Function (anonymous)],
      error: [Function (anonymous)],
      socket: [Function (anonymous)],
      timeout: [Function (anonymous)],
      finish: [Function: requestOnFinish]
    },
    _eventsCount: 7,
    _maxListeners: undefined,
    outputData: [],
    outputSize: 0,
    writable: true,
    destroyed: true,
    _last: false,
    chunkedEncoding: false,
    shouldKeepAlive: true,
    maxRequestsOnConnectionReached: false,
    _defaultKeepAlive: true,
    useChunkedEncodingByDefault: true,
    sendDate: false,
    _removedConnection: false,
    _removedContLen: false,
    _removedTE: false,
    strictContentLength: false,
    _contentLength: '2',
    _hasBody: true,
    _trailer: '',
    finished: true,
    _headerSent: true,
    _closed: true,
    socket: Socket {
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'localhost',
      _closeAfterHandlingError: false,
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 6,
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: null,
      _server: null,
      timeout: 5000,
      parser: null,
      _httpMessage: null,
      autoSelectFamilyAttemptedAddresses: [Array],
      [Symbol(async_id_symbol)]: -1,
      [Symbol(kHandle)]: [TCP],
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: Timeout {
        _idleTimeout: 5000,
        _idlePrev: [TimersList],
        _idleNext: [TimersList],
        _idleStart: 42668240,
        _onTimeout: [Function: bound ],
        _timerArgs: undefined,
        _repeat: null,
        _destroyed: false,
        [Symbol(refed)]: false,
        [Symbol(kHasPrimitive)]: false,
        [Symbol(asyncId)]: 414363,
        [Symbol(triggerId)]: 414361,
        [Symbol(kResourceStore)]: [Object],
        [Symbol(kResourceStore)]: [Object],
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: [Object],
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined
      },
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kSetNoDelay)]: true,
      [Symbol(kSetKeepAlive)]: true,
      [Symbol(kSetKeepAliveInitialDelay)]: 1,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0
    },
    _header: 'POST /souci/capture/ HTTP/1.1\r\n' +
      'Accept: application/json, text/plain, */*\r\n' +
      'Content-Type: application/json\r\n' +
      'X-CSRFToken: pidNq708bHWYkM5HiIV5RsqFJGNKYogsuvkeFxVWtCmkgtaUvOFfzerSyx7lNh0h\r\n' +
      'CSRF-Token: pidNq708bHWYkM5HiIV5RsqFJGNKYogsuvkeFxVWtCmkgtaUvOFfzerSyx7lNh0h\r\n' +
      'User-Agent: axios/1.6.7\r\n' +
      'Content-Length: 2\r\n' +
      'Accept-Encoding: gzip, compress, deflate, br\r\n' +
      'Host: localhost:8000\r\n' +
      'Connection: keep-alive\r\n' +
      '\r\n',
    _keepAliveTimeout: 0,
    _onPendingData: [Function: nop],
    agent: Agent {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      defaultPort: 80,
      protocol: 'http:',
      options: [Object: null prototype],
      requests: [Object: null prototype] {},
      sockets: [Object: null prototype] {},
      freeSockets: [Object: null prototype],
      keepAliveMsecs: 1000,
      keepAlive: true,
      maxSockets: Infinity,
      maxFreeSockets: 256,
      scheduling: 'lifo',
      maxTotalSockets: Infinity,
      totalSocketCount: 1,
      [Symbol(kCapture)]: false
    },
    socketPath: undefined,
    method: 'POST',
    maxHeaderSize: undefined,
    insecureHTTPParser: undefined,
    joinDuplicateHeaders: undefined,
    path: '/souci/capture/',
    _ended: true,
    res: IncomingMessage {
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 4,
      _maxListeners: undefined,
      socket: null,
      httpVersionMajor: 1,
      httpVersionMinor: 1,
      httpVersion: '1.1',
      complete: true,
      rawHeaders: [Array],
      rawTrailers: [],
      joinDuplicateHeaders: undefined,
      aborted: false,
      upgrade: false,
      url: '',
      method: null,
      statusCode: 403,
      statusMessage: 'Forbidden',
      client: [Socket],
      _consuming: false,
      _dumped: false,
      req: [Circular *1],
      responseUrl: 'http://localhost:8000/souci/capture/',
      redirects: [],
      [Symbol(kCapture)]: false,
      [Symbol(kHeaders)]: [Object],
      [Symbol(kHeadersCount)]: 18,
      [Symbol(kTrailers)]: null,
      [Symbol(kTrailersCount)]: 0
    },
    aborted: false,
    timeoutCb: null,
    upgradeOrConnect: false,
    parser: null,
    maxHeadersCount: null,
    reusedSocket: true,
    host: 'localhost',
    protocol: 'http:',
    _redirectable: Writable {
      _writableState: [WritableState],
      _events: [Object: null prototype],
      _eventsCount: 3,
      _maxListeners: undefined,
      _options: [Object],
      _ended: true,
      _ending: true,
      _redirectCount: 0,
      _redirects: [],
      _requestBodyLength: 2,
      _requestBodyBuffers: [],
      _onNativeResponse: [Function (anonymous)],
      _currentRequest: [Circular *1],
      _currentUrl: 'http://localhost:8000/souci/capture/',
      [Symbol(kCapture)]: false
    },
    [Symbol(kCapture)]: false,
    [Symbol(kBytesWritten)]: 0,
    [Symbol(kNeedDrain)]: false,
    [Symbol(corked)]: 0,
    [Symbol(kOutHeaders)]: [Object: null prototype] {
      accept: [Array],
      'content-type': [Array],
      'x-csrftoken': [Array],
      'csrf-token': [Array],
      'user-agent': [Array],
      'content-length': [Array],
      'accept-encoding': [Array],
      host: [Array]
    },
    [Symbol(errored)]: null,
    [Symbol(kHighWaterMark)]: 16384,
    [Symbol(kRejectNonStandardBodyWrites)]: false,
    [Symbol(kUniqueHeaders)]: null
  },
  response: {
    status: 403,
    statusText: 'Forbidden',
    headers: Object [AxiosHeaders] {
      date: 'Tue, 20 Feb 2024 15:27:22 GMT',
      server: 'WSGIServer/0.2 CPython/3.9.6',
      'content-type': 'text/html; charset=utf-8',
      'content-length': '2870',
      vary: 'origin',
      'x-frame-options': 'DENY',
      'x-content-type-options': 'nosniff',
      'referrer-policy': 'same-origin',
      'cross-origin-opener-policy': 'same-origin'
    },
    config: {
      transitional: [Object],
      adapter: [Array],
      transformRequest: [Array],
      transformResponse: [Array],
      timeout: 0,
      xsrfCookieName: 'XSRF-TOKEN',
      xsrfHeaderName: 'X-CSRFToken',
      maxContentLength: -1,
      maxBodyLength: -1,
      env: [Object],
      validateStatus: [Function: validateStatus],
      headers: [Object [AxiosHeaders]],
      withCredentials: true,
      method: 'post',
      url: 'http://localhost:8000/souci/capture/',
      data: '{}'
    },
    request: <ref *1> ClientRequest {
      _events: [Object: null prototype],
      _eventsCount: 7,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      destroyed: true,
      _last: false,
      chunkedEncoding: false,
      shouldKeepAlive: true,
      maxRequestsOnConnectionReached: false,
      _defaultKeepAlive: true,
      useChunkedEncodingByDefault: true,
      sendDate: false,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      strictContentLength: false,
      _contentLength: '2',
      _hasBody: true,
      _trailer: '',
      finished: true,
      _headerSent: true,
      _closed: true,
      socket: [Socket],
      _header: 'POST /souci/capture/ HTTP/1.1\r\n' +
        'Accept: application/json, text/plain, */*\r\n' +
        'Content-Type: application/json\r\n' +
        'X-CSRFToken: pidNq708bHWYkM5HiIV5RsqFJGNKYogsuvkeFxVWtCmkgtaUvOFfzerSyx7lNh0h\r\n' +
        'CSRF-Token: pidNq708bHWYkM5HiIV5RsqFJGNKYogsuvkeFxVWtCmkgtaUvOFfzerSyx7lNh0h\r\n' +
        'User-Agent: axios/1.6.7\r\n' +
        'Content-Length: 2\r\n' +
        'Accept-Encoding: gzip, compress, deflate, br\r\n' +
        'Host: localhost:8000\r\n' +
        'Connection: keep-alive\r\n' +
        '\r\n',
      _keepAliveTimeout: 0,
      _onPendingData: [Function: nop],
      agent: [Agent],
      socketPath: undefined,
      method: 'POST',
      maxHeaderSize: undefined,
      insecureHTTPParser: undefined,
      joinDuplicateHeaders: undefined,
      path: '/souci/capture/',
      _ended: true,
      res: [IncomingMessage],
      aborted: false,
      timeoutCb: null,
      upgradeOrConnect: false,
      parser: null,
      maxHeadersCount: null,
      reusedSocket: true,
      host: 'localhost',
      protocol: 'http:',
      _redirectable: [Writable],
      [Symbol(kCapture)]: false,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype],
      [Symbol(errored)]: null,
      [Symbol(kHighWaterMark)]: 16384,
      [Symbol(kRejectNonStandardBodyWrites)]: false,
      [Symbol(kUniqueHeaders)]: null
    },
    data: '\n' +
      '<!DOCTYPE html>\n' +
      '<html lang="en">\n' +
      '<head>\n' +
      '  <meta http-equiv="content-type" content="text/html; charset=utf-8">\n' +
      '  <meta name="robots" content="NONE,NOARCHIVE">\n' +
      '  <title>403 Forbidden</title>\n' +
      '  <style type="text/css">\n' +
      '    html * { padding:0; margin:0; }\n' +
      '    body * { padding:10px 20px; }\n' +
      '    body * * { padding:0; }\n' +
      '    body { font:small sans-serif; background:#eee; color:#000; }\n' +
      '    body>div { border-bottom:1px solid #ddd; }\n' +
      '    h1 { font-weight:normal; margin-bottom:.4em; }\n' +
      '    h1 span { font-size:60%; color:#666; font-weight:normal; }\n' +
      '    #info { background:#f6f6f6; }\n' +
      '    #info ul { margin: 0.5em 4em; }\n' +
      '    #info p, #summary p { padding-top:10px; }\n' +
      '    #summary { background: #ffc; }\n' +
      '    #explanation { background:#eee; border-bottom: 0px none; }\n' +
      '  </style>\n' +
      '</head>\n' +
      '<body>\n' +
      '<div id="summary">\n' +
      '  <h1>Forbidden <span>(403)</span></h1>\n' +
      '  <p>CSRF verification failed. Request aborted.</p>\n' +
      '\n' +
      '\n' +
      '  <p>You are seeing this message because this site requires a CSRF cookie when submitting forms. This cookie is required for security reasons, to ensure that your browser is not being hijacked by third parties.</p>\n' +
      '  <p>If you have configured your browser to disable cookies, please re-enable them, at least for this site, or for “same-origin” requests.</p>\n' +
      '\n' +
      '</div>\n' +
      '\n' +
      '<div id="info">\n' +
      '  <h2>Help</h2>\n' +
      '    \n' +
      '    <p>Reason given for failure:</p>\n' +
      '    <pre>\n' +
      '    CSRF cookie not set.\n' +
      '    </pre>\n' +
      '    \n' +
      '\n' +
      '  <p>In general, this can occur when there is a genuine Cross Site Request Forgery, or when\n' +
      '  <a\n' +
      '  href="https://docs.djangoproject.com/en/4.2/ref/csrf/">Django’s\n' +
      '  CSRF mechanism</a> has not been used correctly.  For POST forms, you need to\n' +
      '  ensure:</p>\n' +
      '\n' +
      '  <ul>\n' +
      '    <li>Your browser is accepting cookies.</li>\n' +
      '\n' +
      '    <li>The view function passes a <code>request</code> to the template’s <a\n' +
      '    href="https://docs.djangoproject.com/en/dev/topics/templates/#django.template.backends.base.Template.render"><code>render</code></a>\n' +
      '    method.</li>\n' +
      '\n' +
      '    <li>In the template, there is a <code>{% csrf_token\n' +
      '    %}</code> template tag inside each POST form that\n' +
      '    targets an internal URL.</li>\n' +
      '\n' +
      '    <li>If you are not using <code>CsrfViewMiddleware</code>, then you must use\n' +
      '    <code>csrf_protect</code> on any views that use the <code>csrf_token</code>\n' +
      '    template tag, as well as those that accept the POST data.</li>\n' +
      '\n' +
      '    <li>The form has a valid CSRF token. After logging in in another browser\n' +
      '    tab or hitting the back button after a login, you may need to reload the\n' +
      '    page with the form, because the token is rotated after a login.</li>\n' +
      '  </ul>\n' +
      '\n' +
      '  <p>You’re seeing the help section of this page because you have <code>DEBUG =\n' +
      '  True</code> in your Django settings file. Change that to <code>False</code>,\n' +
      '  and only the initial error message will be displayed.  </p>\n' +
      '\n' +
      '  <p>You can customize this page using the CSRF_FAILURE_VIEW setting.</p>\n' +
      '</div>\n' +
      '\n' +
      '</body>\n' +
      '</html>\n'
  }
}

This is a different error:

CSRF Verification failure and not CSRF cookie not set.

The next thing I would look at would be the order that you have your middleware defined. From the docs at django-cors-headers · PyPI

CorsMiddleware should be placed as high as possible, especially before any middleware that can generate responses such as Django’s CommonMiddleware or Whitenoise’s WhiteNoiseMiddleware.

I see where you have django.middleware.common.CommonMiddleware defined twice in your MIDDLEWARE settings. I’d delete that second instance at the bottom and more the CorsMiddleware to before the first instance of it.

made the change. still getting the same errors. any chance this line in settings.py has an effect on it?

ALLOWED_HOSTS = []

Please show the change made and the results.

It may be possible, but I would find it surprising. (Generally, if that is an issue, you get a different error & response.) It certainly wouldn’t hurt to fix it.

Changes:
settings.py

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

route.ts (from next.js) remains the same

export async function POST(req: Request) {

  const { imageData } = req.body; 
  console.log("we're are /capture post, trial 2")
  try {

    // Fetch CSRF token from your Django backend
    const csrfResponse = await axios.get('http://localhost:8000/souci/api/get-csrf-token/');
    const csrfToken = csrfResponse.data.csrf_token;

    console.log("cookies!!!")
    console.log(csrfToken)

    axios.defaults.xsrfHeaderName = 'X-CSRFToken';

    //Django backend
    const response = await axios.post(
      'http://localhost:8000/souci/capture/', 
      { imageData },
      {
        headers: {
          'X-CSRFToken': csrfToken,
          'CSRF-Token': csrfToken,
        },
        withCredentials: true
      }
    );

    return NextResponse.json({response});
  } catch (error) {
    console.error('Error sending image data to Django:', error);
    return NextResponse.json({ success: false, error: 'Failed to send image data to Django' });
  }
}

Output:

we're are /capture post, trial 2
cookies!!!
iJ9o7Jk2cr2pqzaKY5zvSM6KJHhcYgA4GgvjS96Hw1A7vmI3Rdb40TskPZFo8Dsd
Error sending image data to Django: AxiosError: Request failed with status code 403
    at settle (webpack-internal:///(rsc)/./node_modules/axios/lib/core/settle.js:21:16)
    at IncomingMessage.handleStreamEnd (webpack-internal:///(rsc)/./node_modules/axios/lib/adapters/http.js:513:81)
    at IncomingMessage.emit (node:events:526:35)
    at endReadableNT (node:internal/streams/readable:1589:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
    at Axios.request (webpack-internal:///(rsc)/./node_modules/axios/lib/core/Axios.js:50:49)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async POST (webpack-internal:///(rsc)/./src/app/api/capture/route.ts:21:26)
    at async /Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/compiled/next-server/app-route.runtime.dev.js:6:63809
    at async eU.execute (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/compiled/next-server/app-route.runtime.dev.js:6:53964)
    at async eU.handle (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/compiled/next-server/app-route.runtime.dev.js:6:65062)
    at async doRender (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/base-server.js:1333:42)
    at async cacheEntry.responseCache.get.routeKind (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/base-server.js:1555:28)
    at async DevServer.renderToResponseWithComponentsImpl (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/base-server.js:1463:28)
    at async DevServer.renderPageComponent (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/base-server.js:1856:24)
    at async DevServer.renderToResponseImpl (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/base-server.js:1894:32)
    at async DevServer.pipeImpl (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/base-server.js:911:25)
    at async NextNodeServer.handleCatchallRenderRequest (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/next-server.js:271:17)
    at async DevServer.handleRequestImpl (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/base-server.js:807:17)
    at async /Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/dev/next-dev-server.js:331:20
    at async Span.traceAsyncFn (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/trace/trace.js:151:20)
    at async DevServer.handleRequest (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/dev/next-dev-server.js:328:24)
    at async invokeRender (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/lib/router-server.js:163:21)
    at async handleRequest (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/lib/router-server.js:342:24)
    at async requestHandlerImpl (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/lib/router-server.js:366:13)
    at async Server.requestListener (/Users/sossy/workspace/reMatterSite/frontend/node_modules/next/dist/server/lib/start-server.js:140:13) {
  code: 'ERR_BAD_REQUEST',
  config: {
    transitional: {
      silentJSONParsing: true,
      forcedJSONParsing: true,
      clarifyTimeoutError: false
    },
    adapter: [ 'xhr', 'http' ],
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-CSRFToken',
    maxContentLength: -1,
    maxBodyLength: -1,
    env: { FormData: [Function], Blob: [class Blob] },
    validateStatus: [Function: validateStatus],
    headers: Object [AxiosHeaders] {
      Accept: 'application/json, text/plain, */*',
      'Content-Type': 'application/json',
      'X-CSRFToken': 'iJ9o7Jk2cr2pqzaKY5zvSM6KJHhcYgA4GgvjS96Hw1A7vmI3Rdb40TskPZFo8Dsd',
      'CSRF-Token': 'iJ9o7Jk2cr2pqzaKY5zvSM6KJHhcYgA4GgvjS96Hw1A7vmI3Rdb40TskPZFo8Dsd',
      'User-Agent': 'axios/1.6.7',
      'Content-Length': '2',
      'Accept-Encoding': 'gzip, compress, deflate, br'
    },
    withCredentials: true,
    method: 'post',
    url: 'http://localhost:8000/souci/capture/',
    data: '{}'
  },
  request: <ref *1> ClientRequest {
    _events: [Object: null prototype] {
      abort: [Function (anonymous)],
      aborted: [Function (anonymous)],
      connect: [Function (anonymous)],
      error: [Function (anonymous)],
      socket: [Function (anonymous)],
      timeout: [Function (anonymous)],
      finish: [Function: requestOnFinish]
    },
    _eventsCount: 7,
    _maxListeners: undefined,
    outputData: [],
    outputSize: 0,
    writable: true,
    destroyed: true,
    _last: false,
    chunkedEncoding: false,
    shouldKeepAlive: true,
    maxRequestsOnConnectionReached: false,
    _defaultKeepAlive: true,
    useChunkedEncodingByDefault: true,
    sendDate: false,
    _removedConnection: false,
    _removedContLen: false,
    _removedTE: false,
    strictContentLength: false,
    _contentLength: '2',
    _hasBody: true,
    _trailer: '',
    finished: true,
    _headerSent: true,
    _closed: true,
    socket: Socket {
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'localhost',
      _closeAfterHandlingError: false,
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 6,
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: null,
      _server: null,
      timeout: 5000,
      parser: null,
      _httpMessage: null,
      autoSelectFamilyAttemptedAddresses: [Array],
      [Symbol(async_id_symbol)]: -1,
      [Symbol(kHandle)]: [TCP],
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: Timeout {
        _idleTimeout: 5000,
        _idlePrev: [TimersList],
        _idleNext: [TimersList],
        _idleStart: 3464905,
        _onTimeout: [Function: bound ],
        _timerArgs: undefined,
        _repeat: null,
        _destroyed: false,
        [Symbol(refed)]: false,
        [Symbol(kHasPrimitive)]: false,
        [Symbol(asyncId)]: 26921,
        [Symbol(triggerId)]: 26919,
        [Symbol(kResourceStore)]: [Object],
        [Symbol(kResourceStore)]: [Object],
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: [Object],
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined
      },
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kSetNoDelay)]: true,
      [Symbol(kSetKeepAlive)]: true,
      [Symbol(kSetKeepAliveInitialDelay)]: 1,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0
    },
    _header: 'POST /souci/capture/ HTTP/1.1\r\n' +
      'Accept: application/json, text/plain, */*\r\n' +
      'Content-Type: application/json\r\n' +
      'X-CSRFToken: iJ9o7Jk2cr2pqzaKY5zvSM6KJHhcYgA4GgvjS96Hw1A7vmI3Rdb40TskPZFo8Dsd\r\n' +
      'CSRF-Token: iJ9o7Jk2cr2pqzaKY5zvSM6KJHhcYgA4GgvjS96Hw1A7vmI3Rdb40TskPZFo8Dsd\r\n' +
      'User-Agent: axios/1.6.7\r\n' +
      'Content-Length: 2\r\n' +
      'Accept-Encoding: gzip, compress, deflate, br\r\n' +
      'Host: localhost:8000\r\n' +
      'Connection: keep-alive\r\n' +
      '\r\n',
    _keepAliveTimeout: 0,
    _onPendingData: [Function: nop],
    agent: Agent {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      defaultPort: 80,
      protocol: 'http:',
      options: [Object: null prototype],
      requests: [Object: null prototype] {},
      sockets: [Object: null prototype] {},
      freeSockets: [Object: null prototype],
      keepAliveMsecs: 1000,
      keepAlive: true,
      maxSockets: Infinity,
      maxFreeSockets: 256,
      scheduling: 'lifo',
      maxTotalSockets: Infinity,
      totalSocketCount: 1,
      [Symbol(kCapture)]: false
    },
    socketPath: undefined,
    method: 'POST',
    maxHeaderSize: undefined,
    insecureHTTPParser: undefined,
    joinDuplicateHeaders: undefined,
    path: '/souci/capture/',
    _ended: true,
    res: IncomingMessage {
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 4,
      _maxListeners: undefined,
      socket: null,
      httpVersionMajor: 1,
      httpVersionMinor: 1,
      httpVersion: '1.1',
      complete: true,
      rawHeaders: [Array],
      rawTrailers: [],
      joinDuplicateHeaders: undefined,
      aborted: false,
      upgrade: false,
      url: '',
      method: null,
      statusCode: 403,
      statusMessage: 'Forbidden',
      client: [Socket],
      _consuming: false,
      _dumped: false,
      req: [Circular *1],
      responseUrl: 'http://localhost:8000/souci/capture/',
      redirects: [],
      [Symbol(kCapture)]: false,
      [Symbol(kHeaders)]: [Object],
      [Symbol(kHeadersCount)]: 18,
      [Symbol(kTrailers)]: null,
      [Symbol(kTrailersCount)]: 0
    },
    aborted: false,
    timeoutCb: null,
    upgradeOrConnect: false,
    parser: null,
    maxHeadersCount: null,
    reusedSocket: true,
    host: 'localhost',
    protocol: 'http:',
    _redirectable: Writable {
      _writableState: [WritableState],
      _events: [Object: null prototype],
      _eventsCount: 3,
      _maxListeners: undefined,
      _options: [Object],
      _ended: true,
      _ending: true,
      _redirectCount: 0,
      _redirects: [],
      _requestBodyLength: 2,
      _requestBodyBuffers: [],
      _onNativeResponse: [Function (anonymous)],
      _currentRequest: [Circular *1],
      _currentUrl: 'http://localhost:8000/souci/capture/',
      [Symbol(kCapture)]: false
    },
    [Symbol(kCapture)]: false,
    [Symbol(kBytesWritten)]: 0,
    [Symbol(kNeedDrain)]: false,
    [Symbol(corked)]: 0,
    [Symbol(kOutHeaders)]: [Object: null prototype] {
      accept: [Array],
      'content-type': [Array],
      'x-csrftoken': [Array],
      'csrf-token': [Array],
      'user-agent': [Array],
      'content-length': [Array],
      'accept-encoding': [Array],
      host: [Array]
    },
    [Symbol(errored)]: null,
    [Symbol(kHighWaterMark)]: 16384,
    [Symbol(kRejectNonStandardBodyWrites)]: false,
    [Symbol(kUniqueHeaders)]: null
  },
  response: {
    status: 403,
    statusText: 'Forbidden',
    headers: Object [AxiosHeaders] {
      date: 'Tue, 20 Feb 2024 16:54:21 GMT',
      server: 'WSGIServer/0.2 CPython/3.9.6',
      'content-type': 'text/html; charset=utf-8',
      'x-frame-options': 'DENY',
      'content-length': '2870',
      vary: 'origin',
      'x-content-type-options': 'nosniff',
      'referrer-policy': 'same-origin',
      'cross-origin-opener-policy': 'same-origin'
    },
    config: {
      transitional: [Object],
      adapter: [Array],
      transformRequest: [Array],
      transformResponse: [Array],
      timeout: 0,
      xsrfCookieName: 'XSRF-TOKEN',
      xsrfHeaderName: 'X-CSRFToken',
      maxContentLength: -1,
      maxBodyLength: -1,
      env: [Object],
      validateStatus: [Function: validateStatus],
      headers: [Object [AxiosHeaders]],
      withCredentials: true,
      method: 'post',
      url: 'http://localhost:8000/souci/capture/',
      data: '{}'
    },
    request: <ref *1> ClientRequest {
      _events: [Object: null prototype],
      _eventsCount: 7,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      destroyed: true,
      _last: false,
      chunkedEncoding: false,
      shouldKeepAlive: true,
      maxRequestsOnConnectionReached: false,
      _defaultKeepAlive: true,
      useChunkedEncodingByDefault: true,
      sendDate: false,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      strictContentLength: false,
      _contentLength: '2',
      _hasBody: true,
      _trailer: '',
      finished: true,
      _headerSent: true,
      _closed: true,
      socket: [Socket],
      _header: 'POST /souci/capture/ HTTP/1.1\r\n' +
        'Accept: application/json, text/plain, */*\r\n' +
        'Content-Type: application/json\r\n' +
        'X-CSRFToken: iJ9o7Jk2cr2pqzaKY5zvSM6KJHhcYgA4GgvjS96Hw1A7vmI3Rdb40TskPZFo8Dsd\r\n' +
        'CSRF-Token: iJ9o7Jk2cr2pqzaKY5zvSM6KJHhcYgA4GgvjS96Hw1A7vmI3Rdb40TskPZFo8Dsd\r\n' +
        'User-Agent: axios/1.6.7\r\n' +
        'Content-Length: 2\r\n' +
        'Accept-Encoding: gzip, compress, deflate, br\r\n' +
        'Host: localhost:8000\r\n' +
        'Connection: keep-alive\r\n' +
        '\r\n',
      _keepAliveTimeout: 0,
      _onPendingData: [Function: nop],
      agent: [Agent],
      socketPath: undefined,
      method: 'POST',
      maxHeaderSize: undefined,
      insecureHTTPParser: undefined,
      joinDuplicateHeaders: undefined,
      path: '/souci/capture/',
      _ended: true,
      res: [IncomingMessage],
      aborted: false,
      timeoutCb: null,
      upgradeOrConnect: false,
      parser: null,
      maxHeadersCount: null,
      reusedSocket: true,
      host: 'localhost',
      protocol: 'http:',
      _redirectable: [Writable],
      [Symbol(kCapture)]: false,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype],
      [Symbol(errored)]: null,
      [Symbol(kHighWaterMark)]: 16384,
      [Symbol(kRejectNonStandardBodyWrites)]: false,
      [Symbol(kUniqueHeaders)]: null
    },
    data: '\n' +
      '<!DOCTYPE html>\n' +
      '<html lang="en">\n' +
      '<head>\n' +
      '  <meta http-equiv="content-type" content="text/html; charset=utf-8">\n' +
      '  <meta name="robots" content="NONE,NOARCHIVE">\n' +
      '  <title>403 Forbidden</title>\n' +
      '  <style type="text/css">\n' +
      '    html * { padding:0; margin:0; }\n' +
      '    body * { padding:10px 20px; }\n' +
      '    body * * { padding:0; }\n' +
      '    body { font:small sans-serif; background:#eee; color:#000; }\n' +
      '    body>div { border-bottom:1px solid #ddd; }\n' +
      '    h1 { font-weight:normal; margin-bottom:.4em; }\n' +
      '    h1 span { font-size:60%; color:#666; font-weight:normal; }\n' +
      '    #info { background:#f6f6f6; }\n' +
      '    #info ul { margin: 0.5em 4em; }\n' +
      '    #info p, #summary p { padding-top:10px; }\n' +
      '    #summary { background: #ffc; }\n' +
      '    #explanation { background:#eee; border-bottom: 0px none; }\n' +
      '  </style>\n' +
      '</head>\n' +
      '<body>\n' +
      '<div id="summary">\n' +
      '  <h1>Forbidden <span>(403)</span></h1>\n' +
      '  <p>CSRF verification failed. Request aborted.</p>\n' +
      '\n' +
      '\n' +
      '  <p>You are seeing this message because this site requires a CSRF cookie when submitting forms. This cookie is required for security reasons, to ensure that your browser is not being hijacked by third parties.</p>\n' +
      '  <p>If you have configured your browser to disable cookies, please re-enable them, at least for this site, or for “same-origin” requests.</p>\n' +
      '\n' +
      '</div>\n' +
      '\n' +
      '<div id="info">\n' +
      '  <h2>Help</h2>\n' +
      '    \n' +
      '    <p>Reason given for failure:</p>\n' +
      '    <pre>\n' +
      '    CSRF cookie not set.\n' +
      '    </pre>\n' +
      '    \n' +
      '\n' +
      '  <p>In general, this can occur when there is a genuine Cross Site Request Forgery, or when\n' +
      '  <a\n' +
      '  href="https://docs.djangoproject.com/en/4.2/ref/csrf/">Django’s\n' +
      '  CSRF mechanism</a> has not been used correctly.  For POST forms, you need to\n' +
      '  ensure:</p>\n' +
      '\n' +
      '  <ul>\n' +
      '    <li>Your browser is accepting cookies.</li>\n' +
      '\n' +
      '    <li>The view function passes a <code>request</code> to the template’s <a\n' +
      '    href="https://docs.djangoproject.com/en/dev/topics/templates/#django.template.backends.base.Template.render"><code>render</code></a>\n' +
      '    method.</li>\n' +
      '\n' +
      '    <li>In the template, there is a <code>{% csrf_token\n' +
      '    %}</code> template tag inside each POST form that\n' +
      '    targets an internal URL.</li>\n' +
      '\n' +
      '    <li>If you are not using <code>CsrfViewMiddleware</code>, then you must use\n' +
      '    <code>csrf_protect</code> on any views that use the <code>csrf_token</code>\n' +
      '    template tag, as well as those that accept the POST data.</li>\n' +
      '\n' +
      '    <li>The form has a valid CSRF token. After logging in in another browser\n' +
      '    tab or hitting the back button after a login, you may need to reload the\n' +
      '    page with the form, because the token is rotated after a login.</li>\n' +
      '  </ul>\n' +
      '\n' +
      '  <p>You’re seeing the help section of this page because you have <code>DEBUG =\n' +
      '  True</code> in your Django settings file. Change that to <code>False</code>,\n' +
      '  and only the initial error message will be displayed.  </p>\n' +
      '\n' +
      '  <p>You can customize this page using the CSRF_FAILURE_VIEW setting.</p>\n' +
      '</div>\n' +
      '\n' +
      '</body>\n' +
      '</html>\n'
  }
}

The next thing that I would do would be to see what the full response is from the server from the request to get-csrf-token and compare that with what’s being sent to capture. The log that you’re showing doesn’t include the cookies, so there’s no way to verify that the cookie being sent is the same as the cookie being returned.

Verifying that they are the same will then help determine if the issue is in the browser or the server. (If you can verify that the values are the same, then this is likely a server-configuration issue. If they’re different, then this is likely a browser / JavaScript issue.)

I put a console log after get-csrf-token

// Fetch CSRF token from your Django backend
    const csrfResponse = await axios.get('http://localhost:8000/souci/api/get-csrf-token/');
    console.log("this is csrfResponse ", csrfResponse);
    const csrfToken = csrfResponse.data.csrf_token;

here’s the output

{
  status: 200,
  statusText: 'OK',
  headers: Object [AxiosHeaders] {
    date: 'Tue, 20 Feb 2024 17:14:11 GMT',
    server: 'WSGIServer/0.2 CPython/3.9.6',
    'content-type': 'application/json',
    vary: 'Cookie, origin',
    'x-frame-options': 'DENY',
    'content-length': '82',
    'x-content-type-options': 'nosniff',
    'referrer-policy': 'same-origin',
    'cross-origin-opener-policy': 'same-origin',
    'set-cookie': [
      'csrftoken=OxNfuFWdIi2W6cvXYl5IHLprj8x4Pulh; expires=Tue, 18 Feb 2025 17:14:11 GMT; Max-Age=31449600; Path=/; SameSite=Lax'
    ]
  },
  config: {
    transitional: {
      silentJSONParsing: true,
      forcedJSONParsing: true,
      clarifyTimeoutError: false
    },
    adapter: [ 'xhr', 'http' ],
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    maxBodyLength: -1,
    env: { FormData: [Function], Blob: [class Blob] },
    validateStatus: [Function: validateStatus],
    headers: Object [AxiosHeaders] {
      Accept: 'application/json, text/plain, */*',
      'Content-Type': undefined,
      'User-Agent': 'axios/1.6.7',
      'Accept-Encoding': 'gzip, compress, deflate, br'
    },
    method: 'get',
    url: 'http://localhost:8000/souci/api/get-csrf-token/',
    data: undefined
  },
  request: <ref *1> ClientRequest {
    _events: [Object: null prototype] {
      abort: [Function (anonymous)],
      aborted: [Function (anonymous)],
      connect: [Function (anonymous)],
      error: [Function (anonymous)],
      socket: [Function (anonymous)],
      timeout: [Function (anonymous)],
      finish: [Function: requestOnFinish]
    },
    _eventsCount: 7,
    _maxListeners: undefined,
    outputData: [],
    outputSize: 0,
    writable: true,
    destroyed: true,
    _last: true,
    chunkedEncoding: false,
    shouldKeepAlive: true,
    maxRequestsOnConnectionReached: false,
    _defaultKeepAlive: true,
    useChunkedEncodingByDefault: false,
    sendDate: false,
    _removedConnection: false,
    _removedContLen: false,
    _removedTE: false,
    strictContentLength: false,
    _contentLength: 0,
    _hasBody: true,
    _trailer: '',
    finished: true,
    _headerSent: true,
    _closed: true,
    socket: Socket {
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'localhost',
      _closeAfterHandlingError: false,
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 6,
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: null,
      _server: null,
      timeout: 5000,
      parser: null,
      _httpMessage: null,
      autoSelectFamilyAttemptedAddresses: [Array],
      [Symbol(async_id_symbol)]: -1,
      [Symbol(kHandle)]: [TCP],
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: Timeout {
        _idleTimeout: 5000,
        _idlePrev: [TimersList],
        _idleNext: [Timeout],
        _idleStart: 4654744,
        _onTimeout: [Function: bound ],
        _timerArgs: undefined,
        _repeat: null,
        _destroyed: false,
        [Symbol(refed)]: false,
        [Symbol(kHasPrimitive)]: false,
        [Symbol(asyncId)]: 68820,
        [Symbol(triggerId)]: 68818,
        [Symbol(kResourceStore)]: [Object],
        [Symbol(kResourceStore)]: [Object],
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: [Object],
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined,
        [Symbol(kResourceStore)]: undefined
      },
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kSetNoDelay)]: true,
      [Symbol(kSetKeepAlive)]: true,
      [Symbol(kSetKeepAliveInitialDelay)]: 1,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0
    },
    _header: 'GET /souci/api/get-csrf-token/ HTTP/1.1\r\n' +
      'Accept: application/json, text/plain, */*\r\n' +
      'User-Agent: axios/1.6.7\r\n' +
      'Accept-Encoding: gzip, compress, deflate, br\r\n' +
      'Host: localhost:8000\r\n' +
      'Connection: keep-alive\r\n' +
      '\r\n',
    _keepAliveTimeout: 0,
    _onPendingData: [Function: nop],
    agent: Agent {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      defaultPort: 80,
      protocol: 'http:',
      options: [Object: null prototype],
      requests: [Object: null prototype] {},
      sockets: [Object: null prototype] {},
      freeSockets: [Object: null prototype],
      keepAliveMsecs: 1000,
      keepAlive: true,
      maxSockets: Infinity,
      maxFreeSockets: 256,
      scheduling: 'lifo',
      maxTotalSockets: Infinity,
      totalSocketCount: 1,
      [Symbol(kCapture)]: false
    },
    socketPath: undefined,
    method: 'GET',
    maxHeaderSize: undefined,
    insecureHTTPParser: undefined,
    joinDuplicateHeaders: undefined,
    path: '/souci/api/get-csrf-token/',
    _ended: true,
    res: IncomingMessage {
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 4,
      _maxListeners: undefined,
      socket: null,
      httpVersionMajor: 1,
      httpVersionMinor: 1,
      httpVersion: '1.1',
      complete: true,
      rawHeaders: [Array],
      rawTrailers: [],
      joinDuplicateHeaders: undefined,
      aborted: false,
      upgrade: false,
      url: '',
      method: null,
      statusCode: 200,
      statusMessage: 'OK',
      client: [Socket],
      _consuming: false,
      _dumped: false,
      req: [Circular *1],
      responseUrl: 'http://localhost:8000/souci/api/get-csrf-token/',
      redirects: [],
      [Symbol(kCapture)]: false,
      [Symbol(kHeaders)]: [Object],
      [Symbol(kHeadersCount)]: 20,
      [Symbol(kTrailers)]: null,
      [Symbol(kTrailersCount)]: 0
    },
    aborted: false,
    timeoutCb: null,
    upgradeOrConnect: false,
    parser: null,
    maxHeadersCount: null,
    reusedSocket: false,
    host: 'localhost',
    protocol: 'http:',
    _redirectable: Writable {
      _writableState: [WritableState],
      _events: [Object: null prototype],
      _eventsCount: 3,
      _maxListeners: undefined,
      _options: [Object],
      _ended: true,
      _ending: true,
      _redirectCount: 0,
      _redirects: [],
      _requestBodyLength: 0,
      _requestBodyBuffers: [],
      _onNativeResponse: [Function (anonymous)],
      _currentRequest: [Circular *1],
      _currentUrl: 'http://localhost:8000/souci/api/get-csrf-token/',
      [Symbol(kCapture)]: false
    },
    [Symbol(kCapture)]: false,
    [Symbol(kBytesWritten)]: 0,
    [Symbol(kNeedDrain)]: false,
    [Symbol(corked)]: 0,
    [Symbol(kOutHeaders)]: [Object: null prototype] {
      accept: [Array],
      'user-agent': [Array],
      'accept-encoding': [Array],
      host: [Array]
    },
    [Symbol(errored)]: null,
    [Symbol(kHighWaterMark)]: 16384,
    [Symbol(kRejectNonStandardBodyWrites)]: false,
    [Symbol(kUniqueHeaders)]: null
  },
  data: {
    csrf_token: 'N2ddsKjE8SL5yHTeSOy1rbJxrsSRlPCXrpQiMf5HG0DRuJe1GZtzYMYOAqfL09N4'
  }
}

how do I check what is being sent to capture?

One of the easiest ways is to use the network tab in your browser’s developer tools. It’ll show you all the requests being made and has tabs to show you the details of what is being requested.