Random error: Response to preflight request doesn't pass access control check


I have my application deployed here: https://giftyou.herokuapp.com.
Most of the times everything works fine, but from time to time, the request coming back from Google fails with the following error in the logs:
Failed to load https://accounts.google.com/o/oauth2/auth?scope=profile+email&client_id=1xxx.apps.googleusercontent.com&response_type=code&redirect_uri=https%3A%2F%2Fgiftyou.herokuapp.com: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘https://giftyou.herokuapp.com’ is therefore not allowed access. The response had HTTP status code 405.

I usually try several times and it works. And in the cases when it works, I actually do not see this request in the network tab in Chrome so I am quite puzzled.

Edit: I forgot to say that I am doing client-side authentication (with Angular 4)

It looks like it was an issue with my setup on Google Developer’s console side. Not sure why the error was random though.

I do have a strange behavior that I cannot explain.
I am trying to authenticate using Angular on the client side.
Sometimes, I call my service /authenticate/google and it returns a 200 OK with a token in the payload and things are fine.
Sometimes however (with the same user, from the same browser, it’s just random), it returns a 303 with a https://accounts.google.com/o/oauth2/auth?scope=profile+email&client_id=1xxx.apps.googleusercontent.com&response_type=code&redirect_uri=https%3A%2F%2Fgiftyou.herokuapp.com URL that my browser fails to call (Google returns a 405 saying “The requested URL was not found on this server”). I guess I messed up my config and get a race condition or something like that, but I do not know where to look. I cannot reproduce it locally, it just happens on Heroku :-(. What is the “expected” behavior? Should the browser do this call or the server?

I may have an idea: it seems I am defining authorizationURL whereas the doc says it is not required for client-side authentication. I will try to remove it and test.

Unfortunately if I remove the config, it now randomly complains that it is missing with this stack:

com.mohiva.play.silhouette.api.exceptions.ConfigurationException: [Silhouette][google] Authorization URL is undefined
2017-11-03T14:59:05.440461+00:00 app[web.1]: at scala.Option.getOrElse(Option.scala:121)
2017-11-03T14:59:05.440461+00:00 app[web.1]: at com.mohiva.play.silhouette.impl.providers.OAuth2Provider.$anonfun$handleAuthorizationFlow$1(OAuth2Provider.scala:220)
2017-11-03T14:59:05.440463+00:00 app[web.1]: at scala.util.Success.map(Try.scala:209)
2017-11-03T14:59:05.440462+00:00 app[web.1]: at scala.util.Success.$anonfun$map$1(Try.scala:251)
2017-11-03T14:59:05.440464+00:00 app[web.1]: at scala.concurrent.Future.$anonfun$map$1(Future.scala:287)
2017-11-03T14:59:05.440464+00:00 app[web.1]: at scala.concurrent.impl.Promise.liftedTree1$1(Promise.scala:29)
2017-11-03T14:59:05.440465+00:00 app[web.1]: at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:29)
2017-11-03T14:59:05.440466+00:00 app[web.1]: at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
2017-11-03T14:59:05.440467+00:00 app[web.1]: at scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask.exec(ExecutionContextImpl.scala:140)

I guess I am missing a config that prevent this method from being called, but I am not sure which one :S.

It seems that your app initiates the OAuth2 authentication flow. For client side authentication, your JS lib (which one do you use?) should do this step. On the second step, you send then only the access token you get from the first step to your backend.

I am using ng2-ui-auth. There was a bug on the client side, and from time to time the json sent to the server was incomplete. Sorry for all the trouble, I did not understand the whole flow but now I am starting to :slight_smile: