ID Token Authentication with Firebase, Node Js (Explained, Github)
In this article, I will show you how to authenticate using Firebase user’s ‘IdToken’ property in Node Js.
First of all, I would like to explain how tokens work.
Token is a safety measure. I explained it at the left; the server creates a unique token for a user then if the user requests anything, the server asks the user to bring the token. If the token is valid or still valid, the server responds. In case of token expire, the server does not respond. Firebase’s IdTokens expire after one hour.
jwt.io is mostly used token library but in this article, I am going to show you how to use Firebase’s IdToken. No worries, operating logics are the same.
Let’s code now;
I suppose you have a client-side which you can make a request. It is not a must but the code will require it. First, start a Node js Server using Express js. Your server.js file should look like;
const express = require('express')
const app = express()
const port = 8080
const cors = require('cors');
app.use(cors());
app.use(express.json());app.get('/', (req, res) => res.send('Hello World!'))app.listen(port, () => console.log(`Example app listening on port ${port}!`))
Okay, the server is ready. Let’s make Firebase and connections ready.
You need to create a firebase project and enable email/password login authentication. Suppose you know it, I will skip this kind of part. Then get your Firebase Config JSON data. This is enough to use but you have to get the service account JSON file too because I am going to use admin functions. Put it in your project folder. You can check it online on how to get it. After you are done, create a fbConfig.js file. And configure your settings like;
require("firebase/auth");
const firebase = require('firebase')
const admin = require('firebase-admin')
const serviceAccount = require("YOUR SERVICE ACCOUNT JSON PATH");var firebaseConfig = {
//YOUR FIREBASE CONFIG
};firebase.initializeApp(firebaseConfig);
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "YOUR DATABASE URL"
});module.exports = { firebase, admin };
By the way, do not forget installing the required packages using npm.
Here I exported firebase and admin. The ‘firebase’ will do my login, signup, and logout. ‘admin’ will do my token stuff. Create another file named user.js to put our functions in. I will show here the login function to explain but you can find more on Github repository below. So you have to add a user to test manually on Firebase.
First, import this;
const { firebase, admin } = require('./fbConfig')
Then this;
exports.login = (req, res) => {firebase.auth().signInWithEmailAndPassword(req.body.email, req.body.password)
.then(function () {
firebase.auth().currentUser.getIdToken(true).then(function (idToken){
res.send(idToken)
res.end()
}).catch(function (error) {
//Handle error
});
}).catch(function (error) {
//Handle error
});
}
At the code above, signInWithEmailAndPassword is the function by Firebase to let you log in. You can log in with the help of express js middlewares like above. You can find out more on https://expressjs.com/en/guide/writing-middleware.html. As I explained token, after you logged in you have to get a token to carry. So inside the ‘.then’ function, I get an IdToken which is a unique token for each session and holds user info. Now all I have to do is send it back to the client. And sent it right in the ‘.then’ function.
If you want, you can create a custom token instead of using IdToken. You should replace inside the first ‘.then’ function with;
admin.auth().createCustomToken(uid)
.then(function (customToken) {
res.send(customToken)
res.end()
})
.catch(function (error) {
//Handle error
});
‘uid’ parameter is your logged-in user’s id. You can have it using firebase currentUser property. Great, the user is logged-in and given the token.
Before I continue, update your server.js file, add the code below;
const fbAuth = require('./fbAuth')const {
login,
userBasedFunc
} = require('./user')app.post('/login', login);
app.get('/userBasedFunc', fbAuth, userBasedFunc);
Now you will ask what is ‘fbAuth’. This function will return the user info if the token is valid. It will work right before userBasedFunc. Then you can access the returning value from userBasedFunc using middlewares. Create a fbAuth.js file and paste the code below;
const { firebase, admin } = require('./fbConfig');module.exports = (req, res, next) => {const token = req.header('Authorization').replace('Bearer', '').trim()var user = firebase.auth().currentUser;
if (user) {
admin.auth().verifyIdToken(token)
.then(function (decodedToken) {
if(decodedToken.uid === user.uid)
{
req.user = user.uid
return next()
}
}).catch(function (error) {
//Handle error
});
} else {
console.log("There is no current user.");
}
};
‘verifyIdToken’ will check the token with the currentUser and return you the user, if it is valid. WARNING: This function will not work if you use the custom token instead of IdToken, you should use a custom token decoder. So, next() is the middleware to carry the data to the called function. All you have to do is, writing ‘req.user’ to access the data in userBasedFunc.
Here is a thing I should inform about, ‘req.header’. This is to receive the token. You should send the token to the server in the authorization header of your call.
Done! I hope you understand. You will find more detailed code in the Github link below;
If you liked the article, you can 👏 the story and share it.