Hi,
i want use the express-session in my nextJS app on firebase cloud functions.
This is my code:
const server = express();
server.use(helmet());
server.set('trust proxy', 1);
server.use(bodyParser.json());
server.use(bodyParser.urlencoded({ extended: true }));
server.use(
session({
store: new FirebaseSession({ // <== connect-session-firebase
database: firebase.database(),
}),
name: 'ws_auth',
secret: 'mysecret',
secure: true,
httpOnly: true,
resave: false,
rolling: true,
cookie: { maxAge: 604800000 }, // week
saveUninitialized: false,
signed: true,
})
);
server.use(function(q, r, n) {
console.log('after session:', q.session);
n();
});
server.post('/api/login', async (req, res) => {
if (!req.body) return res.sendStatus(400);
if (!req.session) return res.sendStatus(400);
try {
const token = req.body.token;
const decodedToken = await firebase.auth().verifyIdToken(token);
console.log('LOGIN SESSION', req.session);
req.session.decodedToken = decodedToken;
res.json({ status: true, decodedToken });
} catch (err) {
res.json({ err });
console.log('ERROR', err);
}
});
server.post('/api/logout', (req, res) => {
req.session.decodedToken = null;
res.json({ status: true });
});
server.get('*', (req, res) => {
console.log('APP', req.session);
handle(req, res);
});
export let app = functions.https.onRequest(async (req, res) => {
await nextApp.prepare();
server(req, res);
});
At the first time the session is created and after login the decodeToken is added to the session in my firebase database.
On my browser the session is created with the right id.
after session: Session {
cookie:
{ path: '/',
_expires: 2017-09-11T10:32:42.976Z,
originalMaxAge: 604800000,
httpOnly: true } }
------------------------------------------------------
LOGIN SESSION Session {
cookie:
{ path: '/',
_expires: 2017-09-11T10:32:42.976Z,
originalMaxAge: 604800000,
httpOnly: true } }
When i send a new request i have this LOG:
after session: Session {
cookie:
{ path: '/',
_expires: 2017-09-11T10:34:06.277Z,
originalMaxAge: 604800000,
httpOnly: true } }
------------------------------------------------------
APP Session {
cookie:
{ path: '/',
_expires: 2017-09-11T10:34:06.277Z,
originalMaxAge: 604800000,
httpOnly: true } }
The session not have the decodeToken info, the client repeat the login and i see this LOG:
after session: Session {
cookie:
{ path: '/',
_expires: 2017-09-11T10:32:42.979Z,
originalMaxAge: 604800000,
httpOnly: true },
decodedToken:
{ // my info... } }
------------------------------------------------------
LOGIN SESSION Session {
cookie:
{ path: '/',
_expires: 2017-09-11T10:32:42.979Z,
originalMaxAge: 604800000,
httpOnly: true },
decodedToken:
{ // my info... } }
Now the session have the decodeToken info...i don't understand because not pass the right session for every request...
For others who have the same issue, the fix is to use '__name' as the name instead of the default name 'connect.sid'
app.use(session({
...
name: '__session'
}));
For anyone else having this issue, I also had to execute req.session.save() inside of the login path for the decoded token to persist.
server.post('/api/login', async (req, res) => {
if (!req.body || !req.session) {
return res.json({ status: 400, err: 'Missing request token' })
}
try {
const decodedToken = await admin.auth().verifyIdToken(req.body.token)
req.session.decodedToken = decodedToken
await new Promise((resolve, reject) =>
req.session.save(err => (err ? reject(err) : resolve())))
return res.json({ status: 200, decodedToken })
} catch (err) {
return res.json({ status: 400, err })
}
})
@sarovin @agentilela How do you handle req.session on client-side navigation? For me, req.session is only available in getInitialProps on the server-rendered requests.
Most helpful comment
For others who have the same issue, the fix is to use '__name' as the name instead of the default name 'connect.sid'