Firebase (sign in with Google) Authentication in Node.js using Firebase UI and Cookie Sessions

Firebase Authentication provides the backend services that are easy-to-use SDKs and ready-made UI libraries to authenticate users to your app.

Prerequisites: Basic knowledge of node, JavaScript and firebase.

Setup: First we need to create a Firebase Project, head over to firebase Console and create a new project. 

I am going to name it SignInWithGoogle

Click on the web to create a web app.



Go to Firebase Settings>Service Account >Generate a new Key. This Key should be remain private, It is advised to keep this in environment variables.

Now go to Authentication tab and turn on Sign in with Google.

Now Create a new project having success.html (with a simple anchor tag, directing to “/ ” root ) and login.html [leave a blank division with id “firebaseui-auth-container”, the place where Firebase UI will be Initialized]

Change console directory to root of your project type by using the following commands in the console

$npm init
$npm install express firebase-admin cookie-parser https fs

Note: The last two packages are only needed if you wanna save cookies in local-host, however, if you will be running a backend on https then there is no need.

filter_none

edit
close

play_arrow

link
brightness_4
code

const express = require("express");
const admin = require("firebase-admin");
const cookieParser = require("cookie-parser");
const https = require('https');
const fs = require('fs');
   
const app = express();
app.use(cookieParser());
   
var key="--BEGIN PRIVATE KEY--\nMIIEvgIBADANBgk"
    + "qhkiG9w0BAQE--your key here--+1d4\n--END"
    + " PRIVATE KEY-\n";
   
admin.initializeApp({
    credential: admin.credential.cert({
        "private_key": key.replace(/\\n/g, '\n'),
        "client_email": "YOUR CLIENT EMAIL HERE",
        "project_id": "YOUR PROJECT ID "
    })
});
   
app.get('/', (req, res) => {
   res.sendFile(__dirname +'/login.html');  
});
   
app.get('/logout', (req, res) => {
    res.clearCookie('__session');
    res.redirect('/');
});
   
app.get('/success', checkCookie, (req, res) => {
    res.sendFile(__dirname + '/success.html');
    console.log("UID of Signed in User is" 
            + req.decodedClaims.uid);
    // You will reach here only if session
    // is working Fine
});
   
app.get('savecookie', (req, res) => {
    const Idtoken=req.query.token;
    setCookie(Idtoken, res);
});
   
// Saving cookies and verify cookies
// Reference : 
   
function savecookie(idtoken, res) {
   
    const expiresIn = 60 * 60 * 24 * 5 * 1000;
    admin.auth().createSessionCookie(idtoken, {expiresIn})
    .then((sessionCookie) => {
       const options = {maxAge: expiresIn, 
                httpOnly: true, secure: true};
   
       admin.auth().verifyIdToken(idtoken)
        .then(function(decodedClaims) {
           res.redirect('/success');
       });
    }, error => {
        res.status(401).send("UnAuthorised Request");
    });
}
   
function checkCookie(req, res, next) {
   
    const sessionCookie = req.cookies.__session || '';
    admin.auth().verifySessionCookie(
        sessionCookie, true).then((decodedClaims) => {
            req.decodedClaims = decodedClaims;
            next();
        })
        .catch(error => {
  
           // Session cookie is unavailable or invalid. 
           // Force user to login.
           res.redirect('/');
        });
}

chevron_right


Here is app.js file, If you look it closely, you will find that there is no port listening to our request. This is where we need those two node modules.

Most browsers does’t allow you to save cookies in local host, that’s why we will setup HTTPS connection for our localhost.



Make sure you are in root directory of project.

Open bash and type

$openssl req -nodes -new -x509 -keyout server.key -out server.cert

Two files (server.key and server.cert) will be generated.

Add the following code to app.js file-

filter_none

edit
close

play_arrow

link
brightness_4
code

https.createServer({
    key: fs.readFileSync('server.key'),
    cert: fs.readFileSync('server.cert')
  }, app)
  .listen(3000, function () {
    console.log('listening on port 3000!'
      + ' Go to https://localhost:3000/')
  });

chevron_right


Load this script before body tag in login page

filter_none

edit
close

play_arrow

link
brightness_4
code

     
<!-- Firebase Package-->
<script src=
</script>
  
<!-- Loads the login UI elements-->
<script src=
</script>
<link type="text/css" rel="stylesheet" href=

chevron_right


Load this script in login page after body tag (fill the config data that you got from firebase console).

filter_none

edit
close

play_arrow

link
brightness_4
code

var config = {
    apiKey: "YOUR_KEY",
    authDomain: "YOUR_DOMAIN",
    databaseURL: "YOURURL",
    projectId: "--",
    storageBucket: "",
    messagingSenderId: "",
    appId: ""
};
  
firebase.initializeApp(config);
firebase.auth().setPersistence(
    firebase.auth.Auth.Persistence.NONE);
  
// FirebaseUI config.
var uiConfig = {
    signInOptions: [
        // Google sign in option
        firebase.auth.GoogleAuthProvider.PROVIDER_ID,
    ],
  
    // Terms of service url/callback.
    tosUrl: '<your-tos-url>',
  
    // Privacy policy url/callback.
    privacyPolicyUrl: function () {
        window.location.assign(
                '<your-privacy-policy-url>');
    },
  
    callbacks: {
        signInSuccess: function (user, 
            credential, redirectUrl) {
              
                // User successfully signed in.
                user.getIdToken().then(function (idToken) {
                    window.location.href = 
                        '/savecookie?idToken=' + idToken;
                }).catch(error => {
                    console.log(error);
                });
            }
    }
};
  
// Initialize the FirebaseUI Widget using Firebase.
var ui = new firebaseui.auth.AuthUI(firebase.auth());
  
// The start method will wait until the DOM is loaded.
ui.start('#firebaseui-auth-container', uiConfig);

chevron_right


Now hit save and run the command   $node app.js

Now go to https://localhost:3000/ and sign in, then close the tab or browser and type https://localhost:3000/success, you will see that you are not redirected to the sign-in page again, instead, you are taken to the success page.

Note: Here it didn’t ask me to select which account to login with the app because I was signed in with only one account, in-case you have signed in with multiple accounts, it will ask you to choose an account to proceed with.

Download My Completed project in case of any error you face or write in the comment

Reference: https://firebase.google.com/docs/auth/admin/manage-cookies




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : nidhi_biet

Article Tags :

1


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.