ForbiddenError: invalid csrf token in express.js

I tried to apply my frontend pages to 2 different servers: Django and Express.js. In Django I used csrf tokens and so I want to use same frontend pages for 2 servers. So I tried to apply csrf tokens to my express server, and I got error when I tried to move to my admin page. In Django all works fine, but smth wrong in Express server. My Express version is 4.19.2. Also I don’t know how to use same html and script.js files for both Django server and Express

So here is my app.js with all settings:

    const express = require('express');
    const mongoose = require('mongoose');
    const session = require('express-session');
    const crypto = require('crypto');
    const path = require('path');
    const routes = require('./routes');
    const dotenv = require('dotenv');
    const csrf = require('csurf');
    const cookieParser = require('cookie-parser');
    const bodyParser = require('body-parser');

    dotenv.config();

    const app = express();
    const port = 3000;

    const secretKey = crypto.randomBytes(32).toString('hex');

    const mongoURI = process.env.MONGODB_URI || 'mongodb://127.0.0.1:27017/mydatabase';
    mongoose.connect(mongoURI, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
    });

    const db = mongoose.connection;

    db.on('error', console.error.bind(console, 'MongoDB connection error:'));
    db.once('open', async () => {
    console.log('Connected to MongoDB');
    });

    app.use(express.static(path.join(__dirname, '..','public')));

    app.use(session({
    secret: secretKey,
    resave: false,
    saveUninitialized: true,
    cookie: { secure: false },
    }));

    app.use(cookieParser());

    const csrfProtection = csrf({ cookie: true });
    app.use(bodyParser.urlencoded({ extended: false }));
    app.use(bodyParser.json());
    app.use(csrfProtection);

    app.use((req, res, next) => {
    res.locals.csrfToken = req.csrfToken();
    res.locals.using_django = false;
    next();
    });

    app.use('/', routes);

    app.get('/public/styles.css', (req, res) => {
    res.sendFile(path.join(__dirname, '..','public', 'styles.css'));
    });

    app.get('/public/script.js', (req, res) => {
    res.sendFile(path.join(__dirname, '..','public', 'script.js'));
    });

    app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, '..', 'views', 'main.html'));
    });

    app.get('/modify-gifs', csrfProtection, (req, res) => {
    if (!req.session.isAuthenticated) {
    res.redirect('/'); 
    return;
    }

    res.sendFile(path.join(__dirname, '..', 'views', 'Modify-GIF.html'));
    });

    app.use((req, res, next) => {
    res.status(404).sendFile(path.join(__dirname, '..', 'views', '404.html'));
    });

    app.listen(port, () => {
    console.log(`Server is running on port ${port}`);
    });

authentification route in routes.js:

    router.post('/check-auth', (req, res) => {
    const { login, password } = req.body;

    if (login === process.env.ADMIN_LOGIN && password === process.env.ADMIN_PASSWORD) {
    req.session.isAuthenticated = true;
    res.status(200).json({ isAuthenticated: true, message: 'Authentication successful' });
      } else {
    req.session.isAuthenticated = false;
    res.status(401).json({ isAuthenticated: false, message: 'Invalid login or password' });
      }
    });

script.js:

    let isAuthenticated = false;
    let csrfToken = '';
    document.addEventListener('DOMContentLoaded', function () {
    csrfToken = getCsrfToken();
    function getCsrfToken() {
        const tokenElement = document.querySelector('meta[name="csrf-token"]');
        if (tokenElement) {
            return tokenElement.getAttribute('content');
        } else {
            console.error('CSRF token not found');
            return '';
        }
    }

    
    });
    function authenticateAndShowTab() { //TODO: fix with sessions
    const login = prompt('Enter login:');
    const password = prompt('Enter password:');

    fetch('/check-auth', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-CSRFToken': csrfToken,
    },
    body: JSON.stringify({ login, password }),
    })
    .then(response => {
            console.log('Response status:', response.status);
            return response.json();
        })
        .then(data => {
            console.log('Response data:', data);
            if (data.isAuthenticated) {
                isAuthenticated = true;
                sessionStorage.setItem('isAuthenticated', 'true');
                showTab('modGif');
            } else {
                isAuthenticated = false;
                alert('Invalid login or password. Please try again.');
            }
        })
    .catch(error => {
      console.error('Error checking authentication:', error);
    });
    }
    function showTab(tabName) {
    const savedAuthStatus = sessionStorage.getItem('isAuthenticated');
    isAuthenticated = savedAuthStatus === 'true';

    if (tabName === 'main') {
    window.location.href = '/'; 
    } else if (tabName === 'modGif') {
    if (!isAuthenticated){
      authenticateAndShowTab();
      return;
    }
    window.location.href = '/modify-gifs';
    }
    }

Also, here is Modify-Gif.html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="csrf-token" content="{{ csrf_token }}">
    <title>Modify GIFs</title>
    <link rel="stylesheet" type="text/css" href="/public/styles.css">
    <script src="/public/script.js"></script>
    </head>
    <body>
    <div id="tabs">
    <button class="tab-button" data-tab="main" onclick="showTab('main')">Main</button>
    <button class="tab-button active-tab" data-tab="modGif" onclick="showTab('modGif')">Modify Gifs</button>
    </div>
  
    <form id="uploadForm" action="/upload" method="post" enctype="multipart/form-data" style="display: block;">
    {% csrf_token %}
    <h2>File Upload</h2>
    <input type="file" name="file">
    <input type="text" name="filename" id="filename" placeholder="Enter GIF name">
    <input type="text" name="attributes" id="attributesInput" placeholder="Enter attributes (comma-separated)">
    <input type="submit" value="Upload File">
    </form>
  

    <div id="ViewGIFForm" style="display: block;">
    <h2>View GIF</h2>
    <input type="text" id="gifIdInput" placeholder="GIF ID">
    <button onclick="openGif()">Open GIF</button>
    <button onclick="deleteGif()">Delete GIF</button>

    <video id="" controls class="styled-video" style="display: none;"></video>
    <img id="gifImage" style="display: none;">
    <div id="gifAttributes"></div>
    <div id="gifName"></div>
    </div>
    <script>

      displayGifList();
      function deleteGif() {
        const gifIdInputDel = document.getElementById('gifIdInput');
        const gifId = gifIdInputDel.value;

        if (!gifId) {
          alert('Please enter GIF ID to delete.');
          return;
        }

        fetch(`/gif/${gifId}`, {
          method: 'DELETE',
          headers: {
            'X-CSRFToken': csrfToken
          }
        })
          .then(response => {
            if (response.ok) {
              console.log('GIF deleted successfully.');
              alert('GIF deleted successfully.');
            } else if (response.status === 404) {
              console.error('GIF not found.');
              alert('GIF not found.');
            } else {
              console.error('Error deleting GIF:', response.status);
              alert('Error deleting GIF.');
            }
          })
          .catch(error => {
            console.error('Error deleting GIF:', error);
            alert('Error deleting GIF.');
          });
    }
    </script>
    </body>
    </html>

and main.html:

   <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="csrf-token" content="{{ csrf_token }}">
    <title>All GIF List</title>
    <link rel="stylesheet" type="text/css" href="/public/styles.css">
    <script src="/public/script.js"></script>
    </head>
    <body>
    <div id="tabs">
    <button class="tab-button active-tab" data-tab="main" onclick="showTab('main')">Main</button>
    <button class="tab-button" data-tab="modGif" onclick="showTab('modGif')">Modify Gifs</button>
    </div>


    <div id="ViewAndDownloadGIFForm" style="display: block;">
    <h2>View and Download GIF</h2>
    <input type="text" id="gifIdInput" placeholder="GIF ID">
    <input type="text" id="downloadFileNameInput" name="filename" placeholder="Enter file name (in Latin)">
    <button onclick="openGif()">Open GIF</button>
    <button onclick="downloadGif()">Download GIF</button>
        
    <video id="" controls class="styled-video" style="display: none;"></video>
    <img id="gifImage" style="display: none;">
    <div id="gifAttributes"></div>
    <div id="gifName"></div>
    </div>
    </body>
    </html>

P.S. Sorry for the possibly stupid question or bad wording. This is my first public question here

I tried to remove the authentication (by commenting out the code) but got the same error when I tried to send a GIF to the database.

Also i tried to include some middleware from this question:

app.use(express.urlencoded({ extended: true }));

To use the same files for different servers, I tried to apply a condition, but it only works on Django (on Express it appears visually on the page):
Modify-Gif.html

    {% if using_django %}
    {% csrf_token %}
     {% else %}
    <input type="hidden" name="_csrf" value="{{ csrf_token }}">
    {% endif %}

Also i tried to replace this:
<meta name="csrf-token" content="{{ csrf_token }}">

to this:
<meta name="csrf-token" content="{{csrfToken}}">
but still i got same error

And if i keep this change i will get error in Django:
Forbidden (CSRF token from the ‘X-Csrftoken’ HTTP header has incorrect length.): /check-auth
[07/Aug/2024 17:19:18] “POST /check-auth HTTP/1.1” 403 2563

Also i tried to replace some code from answer to this question:

app.use(crsfProtection);

to

app.use(crsfProtection());

But then i got error:
return req[cookieKey]
^

TypeError: Cannot read properties of undefined (reading ‘cookies’)