Is there any other way of fetching a URL in Googlescript? - google-apps-script

I am writing a Googlescript to fetch the contents from an internal URL. I want to call that URL through the browser. Currently on calling using fetch, it never hits my internal server.

If your internal server is preventing requests from Apps Script's UrlFetch, you may be able to send your request via HTMLService. However, there are restrictions to this; see HTTP restrictions. For your situation, these restrictions may prevent all such access through Apps Script.
Another (more complicated) approach would be to set up your internal server to allow external access with authorization.

Related

How to debug server-side `redirect_uri_mismatch` error from Google Signin

I'm attempting to use Google Sign-In with a firebase function following Google's documentation for Google Sign-In for server-side apps, however I'm running into a redirect_uri_mismatch error (unlike the examples in that documentation, I am using Google's nodejs SDK).
The general flow I'm following is to use google's javascript SDK to request an offlineAccessCode() from a user, send that access code to the server (firebase function), use the access code to get an access token and refresh token, and save the refresh token for later use (this is the flow outlined in the documentation).
It might seem like the meaning of the term redirect_uri_mismatch is self-explanatory, but, as stated in the linked documentation, The Authorized redirect URI field does not require a value. Redirect URIs are not used with JavaScript APIs. That line comes from the section "Step 1: Create a client ID and client secret" and is explaining how to configure the OAuth client credentials. This is the only time in the documentation that a redirect uri is mentioned, and there is no indication that a redirect URI is needed when the server uses the authorization code to fetch an access token.
Indeed, the concept of a redirect uri doesn't seem to make sense in the context of a cloud function using an access code obtained from a client. If the server needs to supply a matching redirect_uri as the javascript client (which doesn't seem to be specified anywhere), I'm not sure what redirect_uri the javascript client uses.
So with that background, does anyone have any idea how to solve this redirect_uri_mismatch error?
Or, more generally, any pointers on implementing this auth flow (my cloud function is written in javascript using the google nodejs sdk). I'm finding it very hard to debug this issue.
Update
I realized that the reason why the error message says redirect_uri_mismatch is because I had been testing various values as redirect_uri. When I remove the (optional) redirect_uri param from the request, the response from google's servers is invalid_request: Missing parameter redirect_uri. So google's making it clear that it wants a redirect URI, even as the documentation seems to imply that it isn't necessary for this auth flow. As a larger problem, the documentation doesn't seem to describe how to set up a redirect URI for an auth flow on a single page app.
Ah HA! The answer (as given in this other S.O. answer) is to set the redirect_uri to "postmessage" on the server (firebase function in my case). I have no idea where this answer came from (i.e. I haven't been able to find it in the docs), but it works.

How to use OAuth 2.0 with a Google Apps Script library, with a static redirect URL?

I can't figure out how to make a shared Google Apps Script library, that uses OAuth 2.0.
The problem is that the usercallback redirect URL changes, every time I use the library in a different script. However, that means I'd need to add a new app and whitelisted redirect URL to Asana for each spreadsheet I use the script in. I'm using https://github.com/googlesamples/apps-script-oauth2.
Is there a way to always authenticate with the same redirect URL, so that the library I make can be used from any script, without registering a new redirect URL in Asana?
I'm a Developer Advocate here at Asana. If I understand your question correctly, then yes, you'll have to handle the callback separately for each script. For security reasons, we validate that the OAuth app registration registers the same url as an integration actually requests when authenticating. If this weren't true, for instance, it'd be possible to create a malicious script that uses the client_id from a legitimate script but asks for the redirect to go to its own credential-grabbing endpoint. This is fixed if the app that got the client_id on app registration also specifies precisely which endpoint should be the legal endpoint to redirect to. That means each OAuth app needs to have its own unique and consistent redirect URL :(
I suppose you could possibly create a single "router" Google Apps script which would set the state parameter with some user/script pair when hitting Asana's oauth_authorize endpoint and forward the user credentials on to the script that exists behind the router script based on that user/script pair when the response comes back, but it's not super trivial.
One final option would be to use a Personal Access Token to access Asana's API. This one token can be used by an unlimited number of scripts for access. The downside is that this token "looks like you", that is, it takes action on behalf of not a third party user but you yourself - your scripts would be an automated version of the user whose Personal Access Token they use. This can be mitigated to some extent by creating a "bot account" to access our API and giving it access inside of Asana to the projects or teams you want to gather data on. The other downside to this approach is that every script that uses the personal access token will break if you ever revoke the one token, so if that ever happens by either intent or accident, you'll have to update the Personal Access Token information in every script that uses it.
Hopefully this helps you to evaluate the options and choose which one of these options works best for your script.

Using XMLHttpRequest within a Google Sheet Sidebar

I'm trying to make a REST call to a server that has restricted IP access. Therefore, I need to make the call from the client. To do so, I'm trying to use the XMLHttpRequest object within an HTML page loaded in the Google Sheet Sidebar. When I call XHR.send(), however, I always get an exception of the form:
"NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://some.host.com/'."
Does XMLHttpRequest not work within a google sheet sidebar? Is there an alternative?
Thanks.
When you say that the server you're talking to has "restricted IP access" do you mean only whitelisted IP Addresses can call it? Have you added Google's servers to that whitelist?
This answer provides details:
Google App Engine - list of IP addresses?
As does the FAQ here
https://cloud.google.com/appengine/kb/
(see question "Static IP Addresses and App Engine apps").
I've discovered that making XHR requests from the sidebar is in fact possible.
The problem I was running into was that the browser was blocking the request due to it being a cross-origin request. And, unfortunately, I'm not able to add google to the list of acceptable origins on the server I'm communicating with. So, I may be stuck for my particular use case.

Google Apps Script - Server Side Authentication

I would like to use GAS script as some sort of a web service. Basically, I would like to post some parameters and then using Drive service do some manipulations of Google Doc and all of this has to be done from backend, without use of browser. Now I have issue with authentication - When I deploy GAS as a Web App (Execute the app as user accessing the app, Anyone can access app), when trying to execute script via Http request, I get Google Login response (/accounts/ServiceLogin). Obviously user has to authenticate access. I was not able to find if we can apply OAtuh at that point. So my question is - What can be done to achieve this? Is there any mechanism that can be used to atuhenticate to GAS from a server side? Or am I forced to use browser with GAS?
You could have your own authentication check in the Apps Script code. You would have NO security settings with the publishing, but implement your own password check in the Apps Script code. You would set the publish "Execute the app as:" setting to ME, and the setting of "Who has access to the app:" to Anyone, even anonymous. That allows the app to be run by anyone with no authentication. Then create your own authentication by passing a password in the URL search string.
Even though putting a password in the URL search string is encrypted over a HTTPS connection, it's still considered "bad practice", because the search string could be stored in plain text in the browser history. But you aren't going to use a browser.
So, your Apps Script App would read a search string parameter from the URL, and either allow the script to be run or not. You would be implementing your own authentication system.
But you need to evaluate and decide what the security is on your server, or whatever server is sending the request. If you can send a HTTPS request to an Apps Script with a password in the URL search string, and it's not a security concern on your server, or whatever server is sending the HTTPS request, then you can consider that and make your decision.
If you want to get a response back from Apps Script to your server without anything opening up in the browser, use the Content Service:
Google Documentation - Content Service

How to get an OAuth access token from Google Cloud Messaging on a remote server

I have a general comprehension question about OAuth access token retrieval for a Google Chrome Extension.
I have a popup HTML window in the browser that uses Jquery to request data from the server (a LAMP stack on AWS). The data is presented by PHP scripts which access a MySQL database. All very basic stuff.
I now want to implement a push messaging system using Google Cloud Messaging to alert users of new content that they can check. However I don't really understand where I should request the access token and how to listen for the response. I figure it should be in the PHP scripts but all the Google documentation that I've read states the user has to be present in order to allow access to push messaging. That tells me I should put it in the JavaScript but I feel this is a bad idea because every user could potentially request an access token when I think I only need one every 3000 seconds or so. If my app was completely implemented in PHP I'm sure this would be possible and now I'm worried that splitting it up like this leaves push messaging out of the question. Am I missing a crucial detail or just out of luck?
If the data access you need isn't user-specific, then you're right, there's no good reason to get a separate token for each user. Check out https://developers.google.com/accounts/cookbook/roles/Apps which discusses some options.