I am following these steps to connect to Google Cloud SQL from App Engine using Unix sockets. The connection works and I can retreive data from MySQL using "mysql2" npm module, but the server crashes when I try to use MySQL as an express session store using "express-mysql-session" npm module.
I searched online and in the documentation and I did not find any way to use socketPath with "express-mysql-session" and I also did not find any other MySQL session store that would support this connection. Do you know how I could use Cloud SQL as an express session store using Unix sockets from App Engine? I will use another session store like Firestore if not possible...
Thank you very much for your help!
This code works locally but not from App Engine:
const express = require("express");
const session = require("express-session");
const mysql = require('mysql2');
const MySQLStore = require('express-mysql-session')(session);
require("dotenv").config();
const app = express();
let mysqlConnexionOptions={
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
}
if(process.env.INSTANCE_UNIX_SOCKET){
console.log("Found instance_unix_socket in yaml file, running from App engine");
mysqlConnexionOptions.socketPath=process.env.INSTANCE_UNIX_SOCKET;
}else{
console.log("Instance_unix_socket not found in yaml file, running locally");
mysqlConnexionOptions.port=process.env.DB_PORT
mysqlConnexionOptions.host=process.env.DB_HOST
}
const mysqlPool =mysql.createPool(mysqlConnexionOptions).promise();
const sessionStore = new MySQLStore(mysqlConnexionOptions);
app.use(session({
secret:"test",
name:"sid",
cookie:{
sameSite:"strict", // Prevents iFraming
secure:false, // Set to true for https only access on production, false when testing locally
httpOnly:true //prevent js to access it if true
},
store: sessionStore,
resave:false,
saveUninitialized:false
}));
app.get('/', async function (req, res) {
req.session.test = "test!";
console.log(req.session.test);
const test=await mysqlPool.query("SHOW TABLES;");
res.send(test[0][0].Tables_in_db+" "+req.session.test);
})
const PORT = process.env.PORT||8080;
app.listen(PORT,_=>{
console.log(`Nodejs express app server listening on port ${PORT} http://localhost:${PORT}`);
});
This code works from App Engine because the session store was removed. So connection is good with "MySQL2" npm module:
const express = require("express");
const session = require("express-session");
const mysql = require('mysql2');
require("dotenv").config();
const app = express();
let mysqlConnexionOptions={
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
}
if(process.env.INSTANCE_UNIX_SOCKET){
console.log("Found instance_unix_socket in yaml file, running from App engine");
mysqlConnexionOptions.socketPath=process.env.INSTANCE_UNIX_SOCKET;
}else{
console.log("Instance_unix_socket not found in yaml file, running locally");
mysqlConnexionOptions.port=process.env.DB_PORT
mysqlConnexionOptions.host=process.env.DB_HOST
}
const mysqlPool =mysql.createPool(mysqlConnexionOptions).promise();
app.get('/', async function (req, res) {
const test=await mysqlPool.query("SHOW TABLES;");
res.send(test[0][0].Tables_in_db);
})
const PORT = process.env.PORT||8080;
app.listen(PORT,_=>{
console.log(`Nodejs express app server listening on port ${PORT} http://localhost:${PORT}`);
});
I ran into the same problem and managed to solve it. express-mysql-session does not natively support passing in a socket. But there are two workarounds you can try out:
Create a mysql connection using socket, and use this connection to initialize MysqlStore. See this.
Use another library that supports socket. I chose connect-session-sequelize, which connects DB using sequelize. Sequelize is already adopted by my project to manage DB access, so it's a smooth switch for me. You create sequelize instance with socket like this:
return new Sequelize(database, user, password, {
host: host,
dialect: dialect,
dialectOptions: {
socketPath: socket,
},
});
then refer this to create session store with it.