0
votes

I'm creating my fullstack application with Node/Express on the backend, and vanilla Javascript on the forntend. I am developing the login form. I need to use session on the backend.

SO, in the frontend it gets the username and password put in the form. Then, you call the API and that verify, and if is correct, it modify the session and set a value to the username, so in the "special" page you will be recognized as someone that can stay there.

There is a problem, that when I log in the request generates a new session each time, so I added `credentials: 'include' in the fetch request.

Each time I call the API to do this thing, there is the following error: Access to fetch at 'http://localhost:5000/login' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

I tryied to change cors setting, but nothing worked. Here is the code:

server.js file: 127.0.0.1/5000

const express = require('express');
const morgan = require('morgan');
const cors = require('cors');
const cookieParser = require("cookie-parser");
const sessions = require('express-session');

//Import enviromental variabiles
require('dotenv').config();

//Get one day in milliseconds
const oneDay = 86400000;

//Initializing
const app = express(); 
const port = process.env.PORT || 5000;

//Setup session and cookie
app.use(sessions({
    secret: process.env.SECRET,
    saveUninitialized:true,
    cookie: { maxAge: oneDay },
    resave: false 
}));

app.use(cookieParser());

//Let imported functionality working
app.use(
    cors({
        origins: ['localhost:5500', 'http://localhost:5500', 'http://localhost:5000'],
        credentials: true,
        methods: ['GET', 'POST', 'PUT', 'DELETE'],
        allowedHeaders: ['Origin', 'X-Requested-With', 'Content-Type', 'Accept'],
    })
  );
app.use(morgan('dev'));
app.use(express.json());

//Routes
const router = require('./routes/router');
app.use('',router);

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

routes.js (all the routers):

router.post('/login', async (req, res) => {
    const username = req.body.username;
    const password = req.body.password;
    let session = req.session;
    res.header("Access-Control-Allow-Origin", "http://localhost:5500");
    console.log(req.body)

    try {
        const user = await pool.query(
            `SELECT * FROM utente WHERE username= ($1) AND password = MD5($2)`, [username, password]
        );

        if(user.rows.length != 0){
            session.userid=req.body.username;
            res.json({'logged':'true'});
        }else{
            res.json({'logged':'false', 'error':'uncorrect username or password'});
        }
    }catch(err){
        console.error(err.message);
    }
});

router.get('/logged',(req,res) => {
    session=req.session;
    if(session.userid){
        res.send({'logged':'true'});
    }else{
        res.send({'logged':'false'});
    }
});

Login.js (frontend file) 127.0.0.1/5500:

formL.addEventListener("submit", async function(e) {
    e.preventDefault();
    let username = document.getElementById("nome").value;
    let password = document.getElementById("psw").value;
    if (username === "" || password === "") {
        error.style.display = "block";
        error.innerHTML = `<p>Fullfill all the pitches</p>`
    }else{
        let url = "http://localhost:5000/login";
        
        fetch(url, {
            credentials: 'include',
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            }, 
            body: JSON.stringify({
                username: username,
                password: password
            }),
            
        })
        .then(response => response.json())
        .then(data => {console.log(data)})
        .catch(error => console.error('Error:', error));
    }
});

I can't put '*' as 'Access-Control-Allow-Origin''Access-Control-Allow-Origin', because I need the credentials to keep the session on, or when I make the call from the other page, it creates a new request and I will never be logged in the correct way.

I need a way to fix cors so it lets me making the call and use correctly the session, or find another way of doing everything that lets me have the same session. The first possibility is my favourite.

If you can, please help me

Using cross-site cookies is a bad idea to begin with. Some browsers will block them by default.super
SO, what should I do?Poss
Put the frontend and backend on the same origin. Or use an access token or some other kind of identifier in a header with each request.super
So, like on the frontend sends also a tocken to the server, that creates a waitlist for each browser with the right to do that?Poss
I can't use the same originPoss