7

So far I was working with Mongodb and Express. There my whole authentication was done by checking req.user object. From what I saw, Firebase authentication is mostly done in the front end. How can I get req.user to work with Firebase in the back end? I saw a couple of tutorials, but they just showed a couple of methods and went on. I mean to ask more about the logic, but some code examples would probably help.

ReyAnthonyRenacia
  • 17,219
  • 5
  • 37
  • 56
Alex Ironside
  • 4,658
  • 11
  • 59
  • 119

2 Answers2

18

Firebase authentication is mostly done in the front end

Correct. User auth is entirely done client-side when using the provided SDKs from Firebase.

However, if you need to do some special auth, such as integrating with LDAP/AD or some other enterprise shenanigans, then you would need to do custom token creation that client-side SDKs would use to authenticate the user.

How can I get req.user to work with Firebase in the back end?

This is something you will need to implement yourself. The flow client-side would go something like:

  1. User performs auth client-side.
  2. When a user attempts to access your Express API, you will need to retrieve the token from localstorage and send it with your API request.

Let's assume you attach the token on the request header: FIREBASE_AUTH_TOKEN: abc. See Firebase retrieve the user data stored in local storage as firebase:authUser:

So on the server side, using the Firebase Admin SDK, you will retrieve that token and verify it via verifyIdToken. Quick dirty example below of middleware:

const {auth} = require('firebase-admin');
const authService = auth();

exports.requiresAuth = async (req, res, next) => {
    const idToken = req.header('FIREBASE_AUTH_TOKEN');

    // https://firebase.google.com/docs/reference/admin/node/admin.auth.DecodedIdToken
    let decodedIdToken;

    try {
        decodedIdToken = await authService.verifyIdToken(idToken);
    } catch (error) {
        next(error);
        return;
    }

    req.user = decodedIdToken;
    next();
}

You would then use this middleware like so:

const express = require('express');
const router = express.Router();
const {requiresLogin} = require('./my-middleware.js');

router.get('/example', requiresLogin, async (req, res) => {
    console.log(req.user)
})

I hope this gives you an idea of what to do. I haven't worked with Firebase for a while and the information above is what I gathered from looking at the documentation.

Cisco
  • 20,972
  • 5
  • 38
  • 60
  • Ok. It seems like it's gonna be easier to use localstorage as intended by the creators. Thanks for all the work anyway! – Alex Ironside May 17 '18 at 06:55
  • Just a random thought. Since from what I can see Firebase is doing almost everything on the front-end, wouldn't it be better to use it with Angular? – Alex Ironside May 17 '18 at 09:25
  • "Better" is subjective. You use whatever tool **you** need to get the job done. – Cisco May 17 '18 at 10:39
  • @AlexIronside you realise that if you do this kind of stuff on the client side you have serious security issues in your app. – Oliver Dixon Aug 03 '18 at 18:51
  • I ended up using React and checking the user by `firebase.auth()` – Alex Ironside Aug 05 '18 at 14:05
  • Right, but my above answer still stands. You've successfully authenticated a user client side, but you still need to make sure the user is authorized to access your Express server. – Cisco Aug 05 '18 at 15:15
  • Excellent answer, exactly the direction I was looking for. – nodediggity Sep 19 '18 at 17:36
  • are there any performance implications or limitations to keep in mind when calling verifyIdToken() on every request? very good answer. – Phil Ninan Apr 10 '20 at 05:55
0

If you plan to have server side sessions only, you should consider using Firebase session cookies: https://firebase.google.com/docs/auth/admin/manage-sessions.

An example is available to show how to use httpOnly cookies at: https://github.com/firebase/quickstart-nodejs/tree/master/auth-sessions

bojeil
  • 29,642
  • 4
  • 69
  • 76