skip to Main Content

I am trying to send a cookie containing a token from my back end (index.js) to my client side.

but i am failing to see the cookie on the client-side both with dev tools>network>request headers>cookie (missing header)

I also don’t see it in Postman, nor in Safari browser (using Chrome).

this is the part specific for my cookie request:

app.post('/login', async (req,res) => {
    const {email,password} = req.body;
    const userDoc = await User.findOne({email});
    if (userDoc) {
        const passOk = bcrypt.compareSync(password, userDoc.password)
        if (passOk) {
            jwt.sign({email:userDoc.email, id:userDoc._id}, jwtSecret, {}, (err,token) => {
                if (err) throw err;
                res.cookie('token', token).json(userDoc);
            });
        } else {
            res.status(422).json('pass not ok');
        }
    } else {
        res.json('not found');
    }
});

app.get('/profile', (req,res) => {
    const {token} = req.cookies;
    res.json({token});
})

and this is all my backend code:

const express = require('express');
const cors = require('cors');
const mongoose = require("mongoose");
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const User = require('./models/User.js');
const cookieParser = require('cookie-parser');
require('dotenv').config();
const app = express();

const bcryptSalt = bcrypt.genSaltSync(10);
const jwtSecret = 'fasefraw4r5r3wq45wdfgw34twdfg';

app.use(express.json());
app.use(cookieParser());
app.use(cors({
    credentials: true,
    origin: 'http://localhost:5173',
}));

mongoose.connect(process.env.MONGO_URL);

app.get('/test', (req,res) => {
    res.json('test ok')
});

app.post('/register', async (req,res) => {
    const {name,email,password} = req.body;

    try {
        const userDoc = await User.create({
            name,
            email,
            password:bcrypt.hashSync(password, bcryptSalt),
        });
        res.json(userDoc);
    }
    catch(e) {
        res.status(422).json(e);
    }
})

app.post('/login', async (req,res) => {
    const {email,password} = req.body;
    const userDoc = await User.findOne({email});
    if (userDoc) {
        const passOk = bcrypt.compareSync(password, userDoc.password)
        if (passOk) {
            jwt.sign({email:userDoc.email, id:userDoc._id}, jwtSecret, {}, (err,token) => {
                if (err) throw err;
                res.cookie('token', token).json(userDoc);
            });
        } else {
            res.status(422).json('pass not ok');
        }
    } else {
        res.json('not found');
    }
});

app.get('/profile', (req,res) => {
    const {token} = req.cookies;
    res.json({token});
})

console.log("Server is running!")
app.listen(3000);

anybody sees what may be the reason for the cookie not being sent or shown?

This is from a step by step project tutorial:
https://www.youtube.com/watch?v=MpQbwtSiZ7E

Tried to send a token inside a cookie from the back end to the client side, and failed to see it on the client side.

2

Answers


  1. Change

    res.cookie('token', token).json(userDoc);
    

    to:

    res.cookie('token', token, {
      httpOnly: true,  // Prevents client-side JavaScript from accessing the cookie
      secure: false,   // Allows the cookie to be sent over HTTP 
      sameSite: 'Lax', // Allows some cross-site requests but is safer than 'None'
      maxAge: 24 * 60 * 60 * 1000 // Cookie expiration time (e.g., 1 day)
    }).json(userDoc);
    

    And also make sure to add the "useCredentials" flag when making the request on the clientSide. For instance:

    fetch('/your/server_endpoint', {
        method: 'POST',
        mode: 'same-origin',
        redirect: 'follow',
        credentials: 'include', // !!! Don't forget this
        headers: headers,
        body: JSON.stringify({
            first_name: 'John',
            last_name: 'Doe'
        })
    })
    

    or in axios: axios.defaults.withCredentials = true;

    Login or Signup to reply.
  2. Technically @thelearner answer is correct, but don’t do this. Do not put JWT in cookie, even httpOnly cannot protect you from CSRF attack.

    Rather, put the JWT in Local Storage and make the client JS send an HTTP header with the JWT on each request.

    Also! protect Local Storage from XSS by using CSP and sanitize user’s inputs.
    For further protection I recommend OWASP documentation and my guide about secure JWT authentication.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search