How to auth from production nodejs server to get token for google spreadsheets API - node.js

i've implemented Google Spreadsheets API in an nodejs server, on localhost first time it asked to go to some specific url and copy token, i did this and everything was fine.
But on PROD, i see that it asks for the same thing, but i can't do that for PROD server ( i mean that i can't open console like on local machine and insert that code generated by google ).
So, what can i do? How can i make it works for PROD server.
P.S i've already tried with API keys, but it expects OAuth 2 access token.

I'm not sure what you mean. Could you post some code?
Generally when using the Google SDK in Node, you have the standard developer token, and you get a user access token from the user's Google account - whether that's you or anyone else. You can set those in your environment such as a .env file or in your app's settings on something like Heroku. There's no need for a console.

Related

I'm getting a redirect_uri_mismatch when deploying my Node.js app to Heroku using Google OAuth2

I'm tasked with making a server using Node.js which will read emails from a Google account and parse the content from those emails into data we can store in a database. I'm using Google's googleapis package (v103.0.0) in NPM to authenticate/authorize with whichever account we'd like to use.
The issue comes when we try to switch accounts and have the user re-auth. During development on a local machine, the Auth process works as expected:
The client requests an Auth URL.
The server generates a new Auth URL and sends it back to the client.
The client redirects to that URL and the Google Consent Screen is shown.
The client is asked to choose between logged-in Google accounts.
The client authorizes the application and is redirected back to the server with a code.
The server uses the code to generate/save a token, which allows it to use the Gmail API.
However, after deploying to Heroku, the Google Consent Screen no longer allows the user to select an account. Instead, at step 3, it shows this message. In just about every other question related to this error, there's always additional information below the error code/message, but nothing's there for me. I made sure: (1) the domain I'm using in Heroku is verified on the Google Cloud Console, and (2) the redirect_uri within the Node.js application is passing the correct domain to the Auth URL, even while in production.
I can't provide the URL for privacy reasons, but let me know if there's any source code or Cloud Console info I should include.
It didn't take long after posting this question, but I realized I was using an incorrect OAuth 2.0 Client ID type. I was attempting to use "Desktop" when I should've been using "Web application" instead. Take a look at this image to see the difference.
When you select "Web application", you're given some new options: Authorized JavaScript origins, and Authorized redirect URIs. This is where you need to fill out the allowed URIs. Here's a sample of what that should look like.

How to setup OAuth2 connection to Google Identity API within an Electron app safely with redirectUri pointing to localhost?

The context:
I'm trying to develop a desktop app with ElectronJS which needs access to Google APIs. As such, I want my users to be able to connect to their Google account via OAuth2.
As I use Electron, I have no safe way to store a "client-secret" and must use the "mobile app" method.
The problem:
Google keeps rejecting my redirect_uri:
The doc I followed:
The official npm "google-auth-library" package mentions the following regarding OAuth authentication for Electron apps ("OAuth2 with Installed Apps (Electron)" section) :
If you're authenticating with OAuth2 from an installed application (like Electron), you may not want to embed your client_secret inside of the application sources. To work around this restriction, you can choose the iOS application type when creating your OAuth2 credentials in the Google Developers console
As doing so gave me the previously mentionned Error 400, I looked into Google Identity documentation and saw this regarding localhost redirection:
Note that support for the loopback IP address redirect option on mobile apps is DEPRECATED.
My question:
At this point, I suspect that this is the reason Google is responding Error 400 to my requests (but I admit it could be my fault. I just don't understand what I do wrong as I feel like I follow the documentation strictly.)
If so, what are the possible ways to solve the issue ? Knowing that I have strictly 0 budget for this project and so I cannot afford to redirect to a domain I would buy or afford a server acting as proxy between my app and Google APIs.
(The code, if useful)
I use the "complete OAuth2 example" from google-auth-library except I changed the OAuth2Client constructor call to this, following the doc's recommandations:
const oAuth2Client = new OAuth2Client({
clientId: "<the clientID of my project from Google API Console>",
redirectUri: "http://127.0.0.1:3000"
})
In despair, I've tried a whole lot of different URL formats, but nothing works.
Thanks in advance for your help.
OAUTH BEHAVIOUR
An OpenID Connect desktop app uses PKCE without a client secret. According to RFC8252 it then receives the login response on either a loopback URL or via a private URI scheme notification.
The loopback option is fine for a desktop app but should not be used for a mobile app. Conversely, claimed HTTPS redirect URLs work for mobile apps but not desktop apps.
TROUBLESHOOTING YOUR PROBLEM
It is not clear whether your problem is caused by using a loopback URL or something else. To troubleshoot, you can use a couple of demo Electron apps of mine:
Loopback example
Private URI Scheme example
In both cases, edit the desktop.config.json file in the root folder. Replace my AWS Cognito values with your Google values. Then run npm start. See if that gets you any further, and post any follow up questions.

Gmail API Nodejs and PM2 authentication

I have set up code to send emails using Gmail API in Nodejs. It works perfectly well in local machine. It asks to enter a code by visiting URL. Something like,
Authorize this app by visiting this URL: someURL
Enter the code from that page here: copy-paste code here
This is automatically done by Google following Node.js Quickstart for Gmail and it automatically generates token.json. Everything works perfectly fine in development.
Now in production, I deploy my app using PM2 and Nginx. So, now each node server is running in background and logs are generated in files.
I see the above prompt in the log file Enter the code from that page here:. But as the log is piped to the file, I have no way of pasting the code since I don't have access to standard input.
I have tried generating token.json from local and using it in the server which doesn't seem to work.
How do I fix this and is there any way around this?
NOTE: The code to authorize and send mails works just fine. I'm not posting it here because I don't want the question to be cluttered.
If you are trying to make a server application without need of user interaction instead of using regular OAuth you could try to use Service Account.
Although take into account that service accounts don't have the Gmail API per se, so you should enable the Domain-Wide Delegation to impersonate another user of the domain.
If you insist in authenticating a real user, you can retrieve the token.json before implementing PM2 and using it afterwards.
Also you can take a look at these two (1 and 2) github posts that also opens your initial thought of trying to use the stdin to authenticate the user.

How to get OAuth2 token from an EC2 instance with no browser using nodejs google api

I have a node.js app that uses the google drive API to upload a file to a google drive. It is working fine on my local machine. I am now trying to migrate it to an EC2 instance but when I run the app using node, I am unable to verify by visiting the url...
Authorize this app by visiting this url: https://accounts.google.com/o/oauth2/v2/auth?>access_type=offline&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&response_type=code&cl>ient_id=xxxxxxxxxxxx.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoo>b
Not sure how to proceed as there is no browser on the machine - which makes me question if I am using the correct protocol for this application? I get totally confused by all the different options available.
I am basically using the option laid out here: https://developers.google.com/docs/api/quickstart/nodejs
Any pointers would be greatly appreciated.
Following the steps from the NodeJs Drive API quickstart, you can run your application locally the first time, this way the consent screen will be prompted and you'll be able to grant the permissions. With this, a token.json file will be created in your directory which will be used to create refresh tokens used to authorize the subsequent requests. You can upload your application to the EC2 instance with the token.json file included and you won't have to authorize the application again.
You can read more about refreshing an access token with offline access in Google's OAuth documentation.

Azure hosted api bearer tokens wont decrypt with context.DeserializeTicket?

I have 2 webapi2 projects that use the same database. If I'm on localhost I get a bearer token from one I can pass it to the other and the other will properly decrypt it and load the user. However when I publish them to separate urls on azure, I get the one token fine from one but when I pass it to the other I can't get the ticket to load and it gives me the unauthorized response.
I'm testing this by watching the owin AuthenticationTokenProvider.OnRecieve method. When context.DeserializeTicket is called the ticket remains null and the user never gets loaded.
Your first response will likely be about how the machine keys need to be the same between the 2 so they will work. The problem there is
All my online research says that azure machine keys are synced between apps in the same role (ones a web app and the other is a web api app) so this shouldn't be an issue
I can't specify a machine key because the first app has been in production for a while and changing it's machine key would mess up stored passwords etc...
using the machine key used by the production app on the new api nay work but there is no way to get the machine key of an azure web app.
I'm pretty sure this isn't a machine key issue though but I have no idea how to figure this out. Heeeeelllp!

Resources