How to use a Google service account on a Reactjs Firebase project for using APIs? - reactjs

I am trying to integrate a Google service account to my reactjs-Firebase project but I seem to not understand how to do it.
What I have tried:
I selected JSON as my KEY type for the service account and downloaded it to my system and tried to set it using Application default credentials. (didn't work)
but nothing seems to work.
and I don't understand how to use the service account to call API in this react-firebase project.
am I supposed to authenticate it using Application default credentials or some other method.
Expected result: Want to integrate service account to my reactjs-firebase project so that I can call API's without an API key
Actual result: not able to do that.
Thank you for your help.

You should never put a service account embedded on your front-end or any other secrets as anyone using developer tools in browser can see them.
The best approach for you should be the end user providing their credentials that need to be authenticated against your backend. In the backend if the user is authorized you can have access the service account information and make the calls you need.
Specifically on your Firebase you should use the Cloud Secret Manager and access if like this:
const functions = require('firebase-functions');
const { defineSecret } = require('firebase-functions/params');
const serviceAccount = defineSecret('SERVICE_ACCOUNT_KEY');
// get other secrets and do whatever you need...
There is a tutorial here on secrets.
Or you can go straight to the documentation here.

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?

Methods of Authentication in Go for App Engine

I am building a reservation system in Google App Engine using Go. I need 2 forms of authentication in my program.
Public Form -- form built in Angular that is on our public website. I want my front-end to have some sort of credentials.json file to use when requesting the book and getOpenDates endpoints in my RESTful API running in Go on Google App Engine.
Private Companion App -- protected by username and password that the user supplies in my app built in Flutter. The app is requesting many endpoints in App Engine. I would like to use JWT to authenticate this portion, but I'm not 100% sure JWT is what I need.
I'm not sure if this tutorial on Identity Platform is what I want. I'm very new to App Engine and authentication in general, so I am a bit lost.
Please describe how I could implement these authentication methods in my RESTful API in Go running on Google's App Engine. I think I may be able to implement the username/password method using a tutorial like this but I'm very lost on the 1st form of authentication with just a credentials file as authentication. If I'm going in the complete wrong direction to accomplish what I want please tell me, but what I'm looking for is code or a tutorial describing how to authenticate using these 2 methods. Thanks for any help.
From what I understand, you want to have a golang backend API in App Engine that serves both your web frontend (1.) and your users app (2.).
I am going to suppose that any user with username/password can use both your frontends: the web app and the mobile app with these credentials.
The credentials.jsons are not designed to authenticate users of your services, but rather server to server communication.
With that in mind, I have found the guide Session based authentication in golang, that could help you to set up your backend to accept only authenticated requests over HTTPS. The web browser will automatically save the cookie, however you need to store the cookie in your mobile app.
For much more complicated scenarios for authenticating from different webpages, it is required to use OAuth2 as you can see in this thread. If you don't find any of your requirements listed in here it is probably overkill to use Auth0 nor OAuth2.

appengine access via oauth2 python script (replacing ClientLogin)

I have an App Engine project which:
uses google.appengine.api.get_current_user() to handle users (and login:required)
has a URL to collect some data (which requires login)
has Google users but on a custom domain
I used to have a script to pull the data using the old https://www.google.com/accounts/ClientLogin interface, but now that interface is deprecated, I'm trying to work out what I need to do to get OAuth2 working to access my App Engine URL with a user value set.
I have worked my way through OAuth2 for devices to get myself an access key for my script (i.e. I can run it, authenticate in a web browser, then poll for the access key), as described in OAuth2 For Devices.
But I'm not sure:
what scope I should be using to request the access_token compatible with get_current_user(),
how to pass this in my request to App Engine so that it can create the the user header, and
whether I need to modify my app to use this access_token, eg adding callbacks etc
With regards to the last point, user was set by google's front end infrastructure so I’m hoping that that same infrastructure can somehow convert my OAuth access_token into a login name without me needing to update my app to do the callback part, because it should all be in appengine's infrastructure right and user is set before the request comes to my app.

How to Authenticate user, password with Google App Engine + Java?

I need to authenticate user email and password with Google. I am using App Engine + Java environment. Is there any provision in Google APIs ?
currently i am using
ContactService client = new ContactService ("yourCompany-yourAppName-v1");
client.setUserCredentials("user#example.com", "pa$$word");
I need to replace this Google APIs. I need to authenticate user with Google not application.
Please suggest me how can i do this.
In your last comment you say that the google username and password is entered in the client and validated in the server. That is NOT possible, google has deprecated the ability of an app to capture the password and thats excellent.
The only way to do this is with oauth2, BUT addionally you need to pass a special parameter &max_auth_age=0.
At this point this question is basically a duplicate of this: No prompt for re-authentication with OAUth2. Why and how to force it? however I didnt mark duplicate because yours is a different situation.
Explaining oauth in detail is not part of this answer as its explained well in the official documentation and many guides. Do not use the built-in appengine userService. Instead configure appengine pages so they are all public and on top implement oauth2, for example using the existing google+ javascript signin libraries (thou not sure if those let you set the max_auth_age parameter. If not, you need to roll your own oauth2 "client side 3-legged" flow. In that flow, the client will see the google login page every time, and after the client-side flow finishes, the client will end up with an access token which is what it sends to the server to validate that the user entered the correct username and password. If you include the correct scope (userinfo.email scope) then the server can use that access token to ask google the username that generated the token, thus you have validated that the client did login to google and you know their email.
But you will NOT receive the password. Just enough info to authenticate the user.
The question isn't very clear, I'll try to respond in two way.
1) Authenticate users on appengine with custom username and password.
To do that you need the "classic" way, I suggest you to use a framework like Spring with his module "spring-security", take a look at this sample.
2) Authenticate users on appengine with Google Account.
This is the best way I think, you only need to follow this guide.

Modifying GAE Django to Expand the API Scope on User Login

In the standard django package that Google App Engine uses there is a tool for easily creating a login/logout link with this code:
user = users.get_current_user()
context = {
'user': user,
'login': users.create_login_url(self.request.uri),
'logout': users.create_logout_url(self.request.uri)
}
My problem is that I want to make a mashup of some data using the logged in user's google analytics information. I'm sure that I can use the same login link to also request access to their analytics information, but I've not been able to figure out what I need to modify to do that.
What is it that I need to change to request that access?
Unfortunately, if you are using the built in Users API you will have to request access to the user's analytics information using separately from the login to your app.
Alternatively you could use Google's OpenID+OAuth Hybrid protocol, but you will not be able to use the built in Users API. A good starting point for implementing this might be Nick Johnson's AEoid, plus the Python OAuth2 lib.
In either case, you'll access their analytics data using the gdata analytics API.

Resources