Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

GAE not sending cookie . NodeJs application

const app = express();
app.set('trust proxy', true);
app.use(express.json());
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(__dirname));
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
app.use(express.static(path.join(__dirname, 'public', 'scripts')));
app.use(cookieParser());
app.use(morgan('combined'));
app.use(passport.initialize());

function setExpireHeaders(req, res, next) {
    const oneDay = 86400000; // 1 day in milliseconds
    res.setHeader('Expires', new Date(Date.now() + oneDay).toUTCString());
    next();
  }

app.use(setExpireHeaders);
// Load the list of banned words into a Set for quick lookups
const bannedWords = new Set(fs.readFileSync(path.join(__dirname, './banned-words.txt'), 'utf-8').split('\n'));
const uri = MONGODB_URI;
const client = new MongoClient(MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true });

const store = new MongoDBStore({
    uri: uri,
    collection: 'sessions',
    autoReconnect: true,
    autoRemove: 'native' // Default
  });
store.on('error', function(error) {
    console.error('Session store error:', error);
  });
app.use(session({
    secret: JWT_SECRET,
    resave: false,
    saveUninitialized: true,
    store: store,
    cookie: { secure: true}
  })); 
 
Tried everything , but cannot seem to get it to work. The cookie is not being sent with the headers. Deployed to standard environment. Any ideas?
 
app.yaml
instance_class: F4
automatic_scaling:
  min_idle_instances: 1
handlers:
- url: /.*
  script: auto
  secure: always
  redirect_http_response_code: 301
0 3 517
3 REPLIES 3

Hello @abhishek_09 ,

Welcome to Google Cloud Community!

The given code sets up Express.js in Node.js, it's not immediately obvious from your code why the cookies might not be getting sent in the headers.

You can try troubleshooting with these following steps:

1. Ensure HTTPS for secure cookies `(secure: true)`. Secure your connection.
2. Don't miss `httpOnly: true` for session cookie.
3. Set sameSite for cross-origin cookie behavior.
4. Inspect response headers in your browser.
5. Enable trust proxy in Express.js for proxies.
6. Use `res.cookie()` correctly with attributes.
7. Add console logs for code analysis. Debug your code.

Alternatively, if you encounter any further issues, you can refer to this Stack Overflow post which discusses the same problem.

If the provided steps and resources do not resolve your issue, you can contact Google Cloud Support for further assistance.

Hi Julia, Thanks for your reply. I have tried all that. 

app.use(session({
    secret: JWT_SECRET,
    resave: true,
    saveUninitialized: true,
    proxy: true,
    store: store,
    cookie: { secure: true,
        sameSite: 'none',
        httpOnly: true,
        maxAge: 1000 * 60 * 60 * 24 * 7
    }
  }));
sample Logs
 
2023-08-23 03:45:02 default[20230823t033651] Token from cookies: undefined
2023-08-23 03:45:02 default[20230823t033651] 45.119.31.22 - - [23/Aug/2023:03:45:02 +0000] "GET /rate_profile?userId=64e31b7ea2e2c2910900f461&referralId=af9a3a90-59c4-4ba2-89f3-5c24cf8639c2 HTTP/1.1" 302 182 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.58"
2023-08-23 03:45:02 default[20230823t033651] "GET /?referralId=af9a3a90-59c4-4ba2-89f3-5c24cf8639c2 HTTP/1.1" 200
2023-08-23 03:45:03 default[20230823t033651] "GET /logo-min.png HTTP/1.1" 200
2023-08-23 03:45:03 default[20230823t033651] "GET /client.js HTTP/1.1" 304
2023-08-23 03:45:03 default[20230823t033651] "GET /bg-2.jpg HTTP/1.1" 304
2023-08-23 03:45:03 default[20230823t033651] "GET /favicon.ico HTTP/1.1" 200
2023-08-23 03:45:35 default[20230823t033651] "POST /signup?referralId=af9a3a90-59c4-4ba2-89f3-5c24cf8639c2 HTTP/1.1" 200
2023-08-23 03:45:39 default[20230823t033651] ORIGINAL URL FROM SESSION /rate_profile?userId=64e31b7ea2e2c2910900f461&referralId=af9a3a90-59c4-4ba2-89f3-5c24cf8639c2
2023-08-23 03:45:39 default[20230823t033651] FINAL REDIRECT URL /rate_profile?userId=64e31b7ea2e2c2910900f461&referralId=af9a3a90-59c4-4ba2-89f3-5c24cf8639c2
Sometimes the cookie does come, but that is rare.
Strangely when there is a cookie, the originalURL becomes 'undefined'. this is where the user is supposed to go after Signup. Here is the /signup route

app.post('/signup', upload.single('myfile'), async (req, res) => {
try {
winston.info('Received signup request');

const formFields = JSON.parse(req.body.formFields);
const { firstName, lastName, email, password } = formFields;
const referredBy = req.query.referralId; // The ID of the person who referred the user (if any)
const referralId = uuidv4(); // The unique ID for this user to refer others
const hashedPassword = await bcrypt.hash(password, 10);
const user = { firstName, lastName, email, password: hashedPassword, referredBy, referralId };
const userCollection = client.db('instadb').collection('users');
const existingUser = await userCollection.findOne({ email: email });


if (existingUser) {
return res.status(409).json({ error: 'Email already exists' });
}
const result = await userCollection.insertOne(user);

if (result.acknowledged) {
winston.info('User created successfully:', result.insertedId);

// Create a JWT token for the user
const jwtToken = jwt.sign({ userId: result.insertedId }, JWT_SECRET, { expiresIn: '1h' });

// Set the JWT token in a cookie
res.cookie('token', jwtToken);

if (req.file) {
const file = req.file;
const fileContent = file.buffer;
const fileExtension = path.extname(file.originalname);

const filename = `${uuidv4()}${fileExtension}`;
const params = {
Bucket: AWS_BUCKET_NAME,
Key: filename,
Body: fileContent
};

await uploadFileToS3(params, result.insertedId.toString());
winston.info('File uploaded and reference saved');
}

// Retrieve the original URL from the session
const originalUrl = req.session.originalUrl;
console.log('ORIGINAL URL FROM SESSION', req.session.originalUrl)

// Redirect to the original URL if present, otherwise redirect to the user's profile
const redirectUrl = originalUrl ? originalUrl : `/rate_profile?userId=${result.insertedId.toString()}`;
console.log('FINAL REDIRECT URL', redirectUrl)
// Clear the originalUrl from the session
req.session.originalUrl = null;

return res.json({ redirectUrl: redirectUrl });

} else {
winston.error('Failed to create user in MongoDB');
res.status(500).send('Failed to create user');
}
} catch (error) {
winston.error('Error creating user:', error);
res.status(500).json({ error: 'Failed to create user' });
}
}); run out of options to try.

Now, there is a cloud shell quota exceeded error. Creating a case needs standard support, it appears. This is too much hassle for a simple app. Just going to deploy it somewhere else. Thanks for your reply.