How to safely store Firebase credentials in React JS - reactjs

This is a follow-up question from Firebase Multiple Accounts are signed at the same time
So, I want to create a web application using Firebase Authentication, where a user can switch between multiple accounts. The solution to that problem is linked here: https://stackoverflow.com/a/55905698/16925281
From the provided solution, we can get the Firebase credentials for any account and use it to switch. However, how can I safely store the said credentials at Client Side (Preferably, in ReactJS)?

Related

Where should I implement firebase authentication?

Im watching this tutorial that uses the firebase client library in cloud functions to authenticate users. I am starting to doubt wether this is the right approach. Should I do all the authentication in the react app instead? The tutorial explains that the benefit of doing everything server side is that it decreases the amount of things the user has to download to run the application.
That being said, Im having difficulty getting the client library to work with typescript which makes me just want to scrap it. How should I proceed?
It is generally better practice to host authentication (and especially authentication logic) in the back-end, if not for performance, definitely for security reasons.
That said, you can avoid using cloud functions for this authentication with firebase! Here is an alternative super simple video tutorial you may like instead from Fireship: https://www.youtube.com/watch?v=zQyrwxMPm88. The Google Firebase YouTube channel also has many videos on the subject.
Cloud functions are useful for when you want parallel action to be taken in the back-end during or after login, while the useAuthState() react hook is great for when you want parallel action to be taken in the front-end during or after login.
so my view on the best approach to solve this on Firebase is to either:
A) Use the Auth Firebase SDK for your client to create users and sign in users,
B) Do it with the Auth REST API
The end result is the same, you get your users into Firebase and you can sign them in and get their auth tokens. The SDK runs on the client, the REST API runs on the server. Once that's done, you can use the user token and pass it to cloud functions to do whatever you need and check the token validity and permissions server side.
On the cloud functions you're supposed to use the Admin SDK, not the client SDK. And the admin SDK has all privileges. For a more specific reason why you SHOULD NOT use the client SDK on cloud functions, is because it keeps state. So 2 users calling your cloud functions, using the client sdk server side, would result in the same user token, which is an error.
I hope I've solved your problem?

Is google authentication method through firebase safe?

I've used firebase authentication for my react app.But later many people said that firebase authentication is not much secure and they suggest me to go with JWT authentication or passport.js authentication methods.
But I don't want to shift from firebase because of its simpleness.Now I'm thinking to use google authentication signIn method in firebase. Is google authentication in firebase is also not safe? Is it safe to opt google authentication in firebase?
There is nothing particularly "unsafe" about Firebase Authentication, especially compared to other options. If another options meets your specific needs better, then go with it. But without specific details on what you think to be unsafe about Firebase Auth, there is nothing really to say.

Authentication and Authorization in React app

In a .NET app I can add authentication and authorization using web.config and/or IIS. I can also use [Authorize (Roles = "RoleABC")] in a MVC app's controller or action. And even extend the AuthorizationAttribute
I'm looking into creating a React app for intranet use, and reading these tutorials (ReactJS and MS), but can't find authentication/authorization details.
Even though the app will be Single Page App, I still would like to authenticate and authorize users for certain options within the app, just like I can do in MVC app.
Is the only option to do that way is creating Blazor app instead?
For authentication and authorization, you should use auth tokens (like JWT). Your backend should create an auth token when a client logs in to the system and sends it to the client. Your server also should send the authenticated user information to the client (react app) so that you can render correct pages according to the user type. For example, you can render the admin page for an admin type of user, and the guest page for a guest type of user. You can save this user data as JSON in Redux. Hence you can access the user data from any component of your react. Also, in your backend, you must restrict the endpoints according to the auth token which is sent by the client. In the backend of my app, I follow the below steps:
Authentication check -> Authorization check -> controller (endpoint) -> result
React isn't opinionated on this, so it's up to you to design the implementation. A basic way to do this is:
Log in and obtain an authorized JWT token from the backend and include the account ID when you sign it
Store the JWT token in localStorage, store the account info in Redux
Conditionally limit routes based on account info (ie. admin group) on the front end
Have every auth-required API call include the JWT token in the x-auth-token header, then on the backend use middleware to check if it's still valid. You can then also decode the account ID in order to check its privileges so that you can limit API access
This may be helpful: https://medium.com/#faizanv/authentication-for-your-react-and-express-application-w-json-web-tokens-923515826e0#5f52
Not sure whether you still need this - I personally feel we should have something bridging the authZ gap between server and client to make it easy. So I spent a few days on a github project for this purpose, here it is: authzyin.
What I tried to do is to leverage policy based authorization from asp.net core - which I think it's very cool - and automatically bring the same definition to the client to use in React via hooks.
For authentication I am using msal.js against AAD - so authN is done on the client and jwt bearer token auth is used for all requests.
It has a client lib and a server lib which can be used together or separately. Of course it might still be lacking some features - please feel free to take it as a reference (contribution is also welcome).

What is the best way of authenticating an user in an angular application with .net web API?

There are 2 ways for storing authenticated users details & send the same for each web API call.
Save in Cookie.
Save in Local Storage.
In my case, user details will be used in my Web API & I just need a few(around 4 values) details of user. So for me storing user details in browser is suitable. But, no matter if I am using Local storage or Cookie storage, end user can see userDetails (like UserID, tenantID etc. which are values in my DB). So there is a security issue.
To overcome this security issue, if I will use some angular encoding-decoding algorithm, my application will be slow. Is there any work around?
I am using Web API 2 with Owin. It uses a token based authentication and works pretty well, here is the link for my implementation they follow best practices:
http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/
You use a bearer auth token that is sent through to client and api to verify the users. You can also have stuff like refresh tokens for additional layers of security using the interceptor services in your angular app. So the benefit of this is, is that you do not need to store your usernames / hashed passwords etc. using local storage or cookies but only the auth token and this is then sent through to the API to verify the current user.

Firebase for real time feature while keeping my own rest service and backend database?

I have angular JS application that gets data from REST service with sql server backend. I develop and have control on all 3 parts - angular app, rest service and database.
I want to now add pizazz by making this app near real time by using Firebase. My question is - can I keep my current rest service and database for the most part and only use Firebase database and the library minimally and only where necessary to support real time?
You can do this using JSON Web Tokens (JWTs). This is possible because as you mention in your question, you control the REST service and the SQL server. Thus, because the server is trusted you can connect it to your Firebase database by authenticating it using a JWT.
As a result you can keep managing user accounts the way you currently do with the added "pizzaz" of making a subset of data available in "near real time". Firebase app JWTs can be generated with any existing JWT generation library and then signed by a SHA-256 HMAC signature.
Authenticating Servers
Because you are running a trusted server that is connecting your own Firebase database, you can authenticate it in several ways:
Using a Firebase app secret: All authentication methods can accept a Firebase app secret instead of a JWT token. This will grant the
server complete read and write access to the entire Firebase database.
This access will never expire unless it is revoked via the App
Dashboard.
Using a secure JWT with the optional admin claim set to true: This method will grant a server complete read and write access to the
entire Firebase database. This token will expire normally, so it is
important to set the expiration times accordingly.
Using a secure JWT designed to give access to only the pieces of data a server needs to touch: This method is more complicated, but it
is the safest way to authenticate a server as it lets the Security and
Firebase Rules prevent the server from doing anything it's not
supposed to, even if it becomes compromised in some way.
Source: Firebase Documentation -
https://www.firebase.com/docs/web/guide/login/custom.html
Generating Tokens
There are Helper Libraries available for many platforms but for this example I will use the Firebase Token Generator for Node.js made available by Firebase.
Firebase Token Generator for Node.js:
https://github.com/firebase/firebase-token-generator-node
Step 1:
Install the package using either npm or Bower (or compile from source).
Step 2: Copy the app secret from your Firebase instance's dashboard.
Step 3: Generate a token using Node.js by passing your Firebase app secret to the FirebaseTokenGenerator constructor method like this:
var FirebaseTokenGenerator = require("firebase-token-generator");
var tokenGenerator = new FirebaseTokenGenerator("<YOUR_FIREBASE_SECRET>");
var token = tokenGenerator.createToken({uid: "1", some: "arbitrary", data: "here"});

Resources