Use Google APIs Node.js client library with AppEngine Cloud Endpoints? - google-app-engine

I've coded an Java App Engine app that uses Cloud Endpoints. I want to talk to these endpoints from a Node.js app. Is it possible to use the google-api-nodejs-client for this purpose?
I've already tried this:
var googleapis = require('googleapis');
googleapis
.discover('myapiname', 'v1dev', {baseDiscoveryUrl: 'http://localhost:8888/_ah/api/discovery/v1/apis/'})
.execute(function(err, client) {
console.log(err);
console.log(client);
client.myapiname.domains.list().execute(function(err, resp) {
console.log(resp);
});
});
But the library does not discover my endpoint, the callback returns null for err and client looks like this:
{ clients: [],
ops: {},
authClient: null,
undefined:
{ apiMeta: '<html><head><title>Error 404</title></head>\n<body><h2>Error 404</h2></body>\n</html>',
authClient: null,
defaultParams: null } }
I've replaced my real api name with 'myapiname' and of course the URL http://localhost:8888/_ah/api/discovery/v1/apis/ is reachable (it returns me the right discovery JSON if I open it in the browser on the same computer).

have you tried the same code with code deployed on some vm on google app engine.
I tried the same with our app engine url and it works like charm.

Related

Google Oauth2 giving "redirect_uri_mismatch" error in production when redirect uri setup correctly

I have google oauth set up in a react project. It was working fine in development, locally. Once i promoted the oauth client to "production" and modified the JS origin and redirect URIs to production values, yet it gives this error
Error 400: redirect_uri_mismatch
You can't sign in to this app because it doesn't comply with Google's
OAuth 2.0 policy.
If you're the app developer, register the redirect URI in the Google
Cloud Console. Request details:
redirect_uri=http://super-server.herokuapp.com/v1/auth/google/callback
Related developer documentation
These are the authorized redirect URIs within google cloud console:
https://super-server.herokuapp.com/v1/auth/google/callback
https://super-server.herokuapp.com/v1/auth/google/callback/
https://www.super-server.herokuapp.com/v1/auth/google/callback
https://www.super-server.herokuapp.com/v1/auth/google/callback/
As you can see, there are no authorized uri's with an HTTP schema. Theyre not even allowed in production mode. So im not sure where this is coming from, because the server is HTTPS
server:
Any advice?
the redirect uri must exactly match the one you are adding to Google developer console
If you check the error message your app is running with
http://super-server.herokuapp.com/v1/auth/google/callback
All the ones you have added are https
May i suggest fixing your app so that it runs https. I dont think that you will be able to add http as a production redirect uri endpoint.
documentation
Obtaining OAuth 2.0 access tokens
authorization-errors-redirect-uri-mismatch
Node.js
I dont know enough about react.js but with node you should be able to do something like this
const http = require('http');
const https = require('https');
In my case (MERN + passport.js), i had a configuration that looked like:
const googleOptions = {
clientID: config.google.id,
clientSecret: config.google.secret,
passReqToCallback: true,
callbackURL: '/v1/auth/google/callback',
scope: ['profile', 'email']
};
Even though the server, the client && the configuration of the oauth client within google api console were all in production with everything setup for https, for some reason, the callbackURL kept firing with google oauth as http://my-domain.com/v1/auth/google/callback
so this fix may be hacky, but it did fix my oauth issues:
//Google Strategy
const googleOptions = {
clientID: config.google.id,
clientSecret: config.google.secret,
passReqToCallback: true,
callbackURL: config.environment == 'production' ? 'https://super-server.herokuapp.com/v1/auth/google/callback' : '/v1/auth/google/callback',
scope: ['profile', 'email']
};
Looks like the redirect_uri on the client side (React side) is set to http://super-server.herokuapp.com/v1/auth/google/callback
Change the redirect_uri on the client side from (http) http://super-server.herokuapp.com/v1/auth/google/callback to (https) https://super-server.herokuapp.com/v1/auth/google/callback.

$http.get returns index.html using Ionic v1 and Firebase hosting

We currently have a Ionic v1 project that calls an API implemented as a Google App Engine application. This Ionic app runs with Ionic serve, PhoneGap, and when deployed to Android/iOS.
We are now trying to deploy to the web using Firebase hosting.
The initial HTML/JS code all runs correctly until we reach an $http.get call to the Google App Engine. What happens then is that the request reaches the GAE server and is processed correctly there with a response being sent back. But in the client code, the response.data property is the contents of the Firebase application’s index.html rather than the response that was supplied from GAE.
We don’t know why this is happening, or how to fix it, but here are some relevant facts:
When we run the app on a device using PhoneGap or via the Google Playstore, the URL by which we access GAE is the same URL if we were accessing GAE from a browser. But, when we run the app via “ionic serve” we must use a proxy to work around a CORS issue. What we do is to specify a simplified URL in the Ionic code, and then provide a mapping of that simplified URL to the GAE’s actual URL in a file called “ionic.project” which looks something like this:
{
"name": "proxy-example",
"app_id": "",
"proxies": [
{
"path": "/api",
"proxyUrl": "http://cors.api.com/api"
}
]
}
When we attempt to deploy the app via either “firebase deploy” or “firebase serve” we must use the proxy version of the URL in our $http.get call. Otherwise the call does not reach the GAE server at all. It is not clear how Firebase knows to use “ionic.project” for the proxy mapping.
We are not using “Angularfire”, only the standard AngularJS library that is packaged with Ionic 1.x
Thanks for any help you can offer.

Using Error report of Google Cloud Platform with ExpressJS

I switched my ExpressJS application from Heroku to Google App Engine.
Everything works ok now.
But I am curious about how to debug my application if some exceptions happen on GAE.
On heroku, I can do heroku logs -t to trace the errors. I can check the variable printed by console.error(var) as well.
However, I don't know how to do the same thing on GAE.
I have checked logging of Stack Driver, it seems that it only shows some informations of every HTTP request instead of the detailed logs like heroku.
I have found that there is error report service of Stack Driver. It may what I want.
Here is the tutorial telling us how to setup. But the steps are confusing for me.
Does anyone have the experience to setup the error reporting?
I am finding a more clear steps to setup this.
Thanks a lot and appreciated!
For Stackdriver Error Reporting:
You can use code similar to the one advised for Google Compute Engine: https://cloud.google.com/error-reporting/docs/setup/compute-engine#send_exception_data
Here is what worked for me using Express and Winston on App Engine flexible environment:
var winston = require('winston');
winston.add(winston.transports.File, { filename: '/var/log/app_engine/custom_logs/my.errors.json' });
var report = function (err, req) {
var payload = {
serviceContext: {
service: 'my service',
},
message: err.stack,
context: {
httpRequest: {
url: req.originalUrl,
method: req.method,
referrer: req.header('Referer'),
userAgent: req.header('User-Agent'),
remoteIp: req.ip,
responseStatusCode: 500,
}
}
};
winston.error (payload);
};
// Handle errors
app.use(function (err, req, res, next) {
report(err, req);
res.status(500).send(err.response || 'Something broke!');
});
For Stackdriver Logging:
Indeed, the request_log only contains HTTP requests log entries on App Engine flex. Look in the stdout log to see the output of your application.
If you just want to read data from the logs, you can try:
$ gcloud preview app logs read
2016-05-30 18:46:29 default[alpha2] saved to datastore: mountain biking
2016-05-30 18:46:29 default[alpha2] saved to datastore: adventure
2016-05-30 18:46:29 default[alpha2] saved to datastore: mountain bike
2016-05-30 18:46:29 default[alpha2] saved to datastore: cycle sport

Force angular js app on heroku to use http instead of https?

I am querying an "http" API with my app, so every time I access my application on heroku (which is https enabled by default), CORS complains about cross-origin domain requests.
Asking the owner of the API to make it "https" is not an option, so I was wondering if it was possible to force my application to always use http? This is a node.js built application. (More specifically, it is a yeoman-generated angular js app). In Rails, I've seen several posts on Stack OverFlow saying this can be easily done with something like config.force_ssl = false, so I was wondering whether something similar could work for a node.js application (either something in the code or on Heroku specifically).
As a fix, I wrote an AngularJS Factory that routes all https requests to http:
.factory('DisableSSL', function($location, $window){
return {
activate: function() {
if ($location.protocol() !== 'http') {
$window.location.href = $location.absUrl().replace('https', 'http');
}
}
};
})
This factory is included in all of my other controllers and the activate function is called.
Note that this doesn't work if you're using a browser extension like HTTPSEverywhere.

How to call Google Cloud Endpoints RPC API on localhost?

EDIT I posted an issue on this and it should be fixed in release 1.9.16 of Google AppEngine SDK.
https://code.google.com/p/googleappengine/issues/detail?id=11414
I am developing a service using Google Cloud Endpoints.
Both the REST and the RPC API works great when I deploy it on App Engine. However the strange thing is, when I test the service locally (localhost), the REST calls works fine, but I am having trouble with calls using RPC.
My method signature in the backend is:
#ApiMethod(name = "user.updateprofile", httpMethod = HttpMethod.POST)
public UserProfileDto updateProfile(#Named("sessionToken") String sessionToken, UserProfileDto profile) throws UnauthorizedException { return profile; }
For simplicity I am just returning the UserProfileDto directly.
I have tried to execute the following request locally:
POST http://localhost:4567/_ah/api/rpc?prettyPrint=false
Content-Type: application/json-rpc
Accept: application/json-rpc
{
"method": "mobilebackend.user.updateprofile",
"id": "gtl_1",
"jsonrpc": "2.0",
"params": {
"sessionToken": "12345",
"resource": {
"username": "foo",
"userPrivate": true
}
},
"apiVersion": "v1"
}
When I set a breakpoint in the updateProfile method, I see that the sessionToken is correctly 12345 however the username field is null and the userPrivate field is false even though I specified it as true. The instance of UserProfileDto (profile) is not null.
The problem is that it fails to inject the values into the fields of the DTO when using RPC calls localhost. When I test it on the deployed version it works fine, and when I use REST calls it works both on localhost and when deployed on App Engine.
When I change the url in the above request to target the deployed version of my application on app engine it works just fine. https://<app-name>.appspot.com/_ah/api/rpc?prettyPrint=false
I start the service on localhost using:
mvn appengine:devserver
Do I miss some configuration in order to call the Cloud Endpoints RPC methods localhost? Or is it not supported?
I should notice that I have also tried with the auto-generated iOS client library which is using RPC and it also fails with the same error as the service fails to inject the values into the fields of the DTO object.
I have tested release 1.9.17 of Google AppEngine SDK and can confirm that using objects in RPC POST requests now works fine.

Resources