Naresh
Naresh

Reputation: 25793

How to store access tokens in Firebase back-end?

My React app uses Firebase Authentication and the Real-Time Database. I now need to access 3rd party services using OAuth 2.0. To do this securely, I am using the OAuth 2.0 Authorization Code Flow with Firebase Functions as my back-end:

  1. React app gets an Authorization Code from the 3rd party.
  2. Authorization code is passed to a Firebase function to get an access token.

But this is where I am stuck. How do I save the access token in the backend so that the React app can access the 3rd party resources? I don't want to store the access token in the React app because that's not secure.

  1. How do I maintain a session in the back-end using Firebase Functions?
  2. Should the session be tied to the React app instance or the Firebase user? The former approach would require a session cleanup. The latter has the advantage that new access tokens can be obtained using a refresh token. This way the user never has to login to the 3rd party again!

Upvotes: 2

Views: 3275

Answers (2)

Gary Archer
Gary Archer

Reputation: 29243

OVERALL FACTORS

Typically these are the areas that your SPA Security choices influence, and there are trade offs:

  • Type of App
  • Strong Security
  • Hosting and Global Performance
  • Technical Simplicity

IN ALL CASES

Your app should:

  • Maintain a token for each user separately
  • You will want to identify users from tokens after login

OPTION 1: FRONT END MODEL / COOKIELESS

This involves using tokens in the browser and has these benefits:

  • Back end is static content only
  • Web resources can be deployed close to users via a CDN
  • You can use the OIDC Client library to manage security

This is widely used and should only be exploitable if your app has cross site scripting vulnerabilities. Some resources of mine:

OPTION 2: BACK END MODEL / AUTH COOKIES

This involves proxying via a back end and carrying tokens around in authentication cookies. I would use this model if developing an online banking app but for medium security apps it can add a lot of overhead. You may have to write more security code and it is possible to end up with a less secure solution than option 1:

  • Requires a proxy back end that runs code
  • The back end code may need to be clustered and globally distributed, to achieve good performance
  • You need to protect the auth cookie and deal with cross site request forgery risks

Out of interest the respected mod_auth_openidc library can be helpful for this type of solution.

BEST OF BOTH WORLDS

If using tokens in a browser is deemed unacceptable I would aim to follow option 1 as much as possible. Then implement option 2 as an additive step:

  • Deploy web static content separately to the code that does back end token management
  • Continue to use the OIDC Client library, and make the Authorization Code Exchange call your back end
  • The only difference to option 1 is that tokens are not available to browser code

Upvotes: 1

Naresh
Naresh

Reputation: 25793

After trying bunch of different approaches, I ended up storing the access token & the refresh token in the back-end, both tied to the firebase user. The tokens are only accessible through firebase functions. This approach has the following advantages:

  1. Secure
  2. I don't have to worry about sessions and session cleanup.
  3. I can refresh the access token whenever I want using the refresh token.

Upvotes: 1

Related Questions