How to validate Firebase ID token in Ruby

Igor Khomenko
Jul 28, 2017 · 3 min read

Recently our team received a task to integrate user authorisation via Firebase phone auth. A quick investigation of Firebase product directed us to this article about Verify ID Tokens. If you have a Firebase client app which communicates with a custom backend server, you might need to identify the currently signed-in user on that server. To do so securely, after a successful sign-in, send the user’s ID token to your server using HTTPS. Yes, after successful login into Firebase each user receives his own ID token which is actually a JWT token. Then, on the server, verify the integrity and authenticity of the ID token and retrieve the uid from it. You can use the uid transmitted in this way to securely identify the currently signed-in user on your server.

Enough theory. So we started this task, but immediately realised that Firebase do not have the Firebase Admin SDK for Ruby. It’s only for Node.js, Java and Python. D’oh! For guys like us they have a separate section Verify ID tokens using a third-party JWT library , something like DIY. Alright, we took ruby-jwt gem and started our journey.

We spend about 2 days to make it fully workable, so mainly it went smooth. But I would like to share some pit fails with you that are not so obvious when you start.

First of all, you can use my shared web page to sign in via Firebase phone number and obtain the ID Token (they call it accessToken in JSON). If you want you also can setup your own web page, luckily Firebase provides a lot of ready-to-go code samples.

So now you have an accessToken, let’s try to verify it.


Your server API has to receive 2 input parameters: access token and Firebase project ID

The first thing is that if you build REST API, e.g. sign in with Firebase phone, then you need to obtain 2 parameters from client: accessToken and also Firebase project ID. Firebase project ID is used in 2 validations (aud and iss payload parameters), so your server needs it in order to do a proper validation.

Grab public keys from Google server periodically, to validate token signature

The second thing is that you need periodically grab valid public keys. You need these keys to validate your token’s signature and the kid header. Luckily, Google returns the Cache-Control header with max-age param, so we can cache response for some time.

To properly validate your token signature you need to decode it twice

The last but very important thing is that you need to call JWT.decode method twice to validate your token signature properly. After first time you decode your token and obtain headers and payload. Then you take the kid header and obtain a certificate from step 2 which corresponds to this particular kid header. And only then you call again the JWT.decode method where you pass now this public key to decode and validate signature.

You can read an official response from the ruby-jwt maintainers .

That’s all I want to share with you. Full code of ruby class-verifier you can find in my GitHub. Ask me if you have any issues.

Cheers!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store