I have a slight problem, and it seems to be an easy one, but I cannot seem to wrap my head around what to do.
I have an express app, that uses Firebase to store data
The user side, and server side, are completely different execution areas. Hence, as you probably guessed, calling firebase.auth().currentUser
on the server cannot work if the authentication occurred on the client.
The server process just does not have this information, unless the client tells him.
You could just have a request header telling "i am logged as XXX", but it would not be secure, because the server would not be able to verify that information, and a malicious user could pretend to be another one.
The only solution to this, in your use case, is to provide the Firebase token to the server, and then the server needs to verify this token against firebase server, and only then it will be 100% sure about the client authentication.
I needed that in my React app for Server Side Rendering, here is how I did it.
Code in the client :
const setAppCookie = () => firebase.auth().currentUser &&
firebase.auth().currentUser.getToken().then(token => {
cookies.set('token', token, {
domain: window.location.hostname,
expire: 1 / 24, // One hour
path: '/',
secure: true // If served over HTTPS
});
});
const unsetAppCookie = () =>
cookies.remove('token', {
domain: window.location.hostname,
path: '/',
});
// triggered by firebase auth changes, this is where you deal
// with your users authentication in your app
fbAuth.onAuthStateChanged(user => {
if (!user) {
// user is logged out
return;
}
// user is logged in
setAppCookie();
// Reset cookie before hour expires
// (firebase tokens are short lived, say the docs)
setInterval(setAppCookie, 3500);
});
[...]
// In the logout code
unsetAppCookie();
Code in the server:
// Before serving express app, enable cookie parsing
app.use(cookieParser());
// In the code dealing with your requests
const { token } = req.cookies;
if (!token) {
// renderWithoutUser();
}
//
// If user found in cookie, verify the token and render with logged in store
//
console.log('Verifying token', token);
firebase.auth().verifyIdToken(token)
.then(decodedToken => {
const uid = decodedToken.sub;
console.log('User is authenticated for this request', uid);
// renderWithUser();
})
.catch(err => {
console.error('WARNING token invalid or user not found', err);
// renderWithoutUser();
});