Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hybrid Authentification returning null #122

Closed
nicohvi opened this issue May 16, 2014 · 17 comments
Closed

Hybrid Authentification returning null #122

nicohvi opened this issue May 16, 2014 · 17 comments

Comments

@nicohvi
Copy link

nicohvi commented May 16, 2014

I'm trying to use the Hybrid Authentification, but the response I get from the Google Plus API is always null.

$ ->
  Q($.ajax(
    url:'https://apis.google.com/js/client:plus.js?'
    dataType: 'script'
    cache: true
    )
  )
  .then(
    ->
      initGoogleAuth()
      console.log 'Google oauth loaded.'
  )
  .fail(
    (error) ->
      console.log 'failed to initialize Google oauth, are you online brah?'
  )

@initGoogleAuth = ->
  $('.google').on 'click', (event) ->
    event.preventDefault()
    gapi.auth.authorize({
      immediate: true
      response_type: 'code'
      cookie_policy: 'single_host_origin'
      client_id: '<my client-id>'
      scope: 'email profile'
    }
    ,
      (response) ->
        # response is null
    )

Anything in particular I am doing wrong/misunderstanding?

@zquestz
Copy link
Owner

zquestz commented May 17, 2014

Not sure why this is happening, but I am noticing that some of the code in the sample isn't in your coffeescript version. The url in the ajax call should be:

https://apis.google.com/js/client:plus.js?onload=gpAsyncInit

Also make sure you have the API's you need enabled in the console. They are listed in the README.

@petergoldstein
Copy link
Contributor

So it looks like you're attempting to replace the onload function in the URL with a promise that resolves when the AJAX call returns. This conflates two different events:

  1. Google JS is retrieved by AJAX call and parsed
  2. Google code has loaded and is ready to process requests

onload refers to the 2nd of these events, but your promise resolves on the 1st.

Note that we don't use a promise (or callback) in the $.ajax function call in the example. We don't do that for exactly this reason.

@nicohvi
Copy link
Author

nicohvi commented May 18, 2014

@zquestz I tried using both methods (onload and the promise), but the result was always the same - the response object was null. For reference I have enabled the APIs in the development console.

@petergoldstein the result is the same when I don't use a promise. I literally copied and pasted the code from your example into my code (escaped the javascript using the ` character), and the result was still the same. :-/

The code I'm trying now (which still fails) looks like this:

$ ->
  $.ajax
      url:'https://apis.google.com/js/client:plus.js?onload=initGoogleAuth'
      dataType: 'script'
      cache: true

@initGoogleAuth = ->
    gapi.auth.authorize({
      immediate: true
      response_type: 'code'
      cookie_policy: 'single_host_origin'
      client_id: '<my-id>'
      scope: 'email profile'
    }
    ,
      (response) ->
        # response is null
    )

@zquestz
Copy link
Owner

zquestz commented May 18, 2014

So the part that is failing is pretty easy to test. In fact you are breaking before this gem even gets used. Perhaps just try in the javascript console and see if you can get gapi.auth.authorize() to work.

Here are the docs for the part failing:
https://developers.google.com/api-client-library/javascript/reference/referencedocs#gapiauthauthorize

The gem is only used in the callback from gapi.auth.authorize(). The rest should be covered by the doc above.

Good luck and let me know if anything in the docs needs to be updated.

@nicohvi
Copy link
Author

nicohvi commented May 19, 2014

@zquestz I've got it working now, and the reason was indeed as you said that I was calling the API itself incorrectly - thank you very much for pointing that out!

The problem it seems was that I was not setting the API key (which I don't think the docs mention?)

Anyway, the following code is working for me now, in case you want to update the docs regarding API keys and whatnot.

$ => 
  $.ajax
    url:'https://apis.google.com/js/client:plus.js?onload=initGoogleAuth'
    dataType: 'script'
    cache: true

  @initGoogleAuth = ->
    gapi.client.setApiKey(apiKey)

    $('.google').on 'click', (event) ->
      event.preventDefault()
      gapi.auth.authorize
        client_id: clientId
        scope: scope
        immediate: false
        googleAuthCallback

  googleAuthCallback = (authResponse) ->
    # authResponse now properly set.

@nicohvi
Copy link
Author

nicohvi commented May 19, 2014

A new problem I've encountered once I got it working was the following:

Uncaught SecurityError: Blocked a frame with origin "http://localhost:3000" from accessing a frame with
origin "https://accounts.google.com".  The frame requesting access has a protocol of "http", the frame
being accessed has a protocol of "https". Protocols must match.

Does that mean the app using this gem has to run on HTTPS?

@zquestz
Copy link
Owner

zquestz commented May 19, 2014

You should definitely try with immediate set to true. I know there are issues with the popup if this isn't done.

@zquestz
Copy link
Owner

zquestz commented May 19, 2014

@nicohvi
Copy link
Author

nicohvi commented May 19, 2014

That seems to have fixed it, @zquestz (immediate: true) - thank you very much for taking the time to reply :-)

@zquestz zquestz closed this as completed May 23, 2014
@raldred
Copy link

raldred commented Oct 24, 2014

immediate: true does not fix it completely for me.
It corrects the iframe issue but I get and error: immediate_failed back from the authorise call.

@gkopylov
Copy link
Contributor

I have the same problem as @raldred
So I turned back immediate to false. Now on first attempt to authorize I get error "Uncaught SecurityError: Blocked a frame with origin "http://localhost:3000"..." and on the second attempt it authorize correctly.

@raldred
Copy link

raldred commented Oct 25, 2014

I wonder if this a recent issue, either something new in omniauth or Google's api
I'm working on a brand new rails project on 4.1.6 and ruby 2.1.3.
I've used omniauth with devise for years so I sort of expect this to "just work"

@gkopylov
Copy link
Contributor

@raldred as far as I know hybrid client authentication for this gem came with this PR #50 in the past year.

I finally get it works. The solution is not very nice, but at least it works any way. You just need to add two authorize actions, first with immediate false and the last one with immediate true. For example:

      gapi.auth.authorize
        client_id: '<%= Rails.application.secrets.omniauth_google_id %>'
        scope: 'email profile'
        immediate: false
        cookie_policy: 'single_host_origin'
        response_type: 'code'
      , (response) ->
        gapi.auth.authorize
          client_id: '<%= Rails.application.secrets.omniauth_google_id %>'
          scope: 'email profile'
          immediate: true
          cookie_policy: 'single_host_origin'
          response_type: 'code'
        , (response) ->
          if response and not response.error
            $.ajax
              type: 'POST'
              url: '<%= Rails.application.routes.url_helpers.user_omniauth_callback_url('google_oauth2') %>'
              dataType: 'json'
              cookie_policy: 'single_host_origin'
              data: response
            .complete (jqXHR, textStatus) ->
              # handle complete there

          else
            # handle error responce there

@mmahalwy
Copy link

@gkopylov & @raidred is this the best way to do that? Has anything changed to make this better?

@raldred
Copy link

raldred commented May 23, 2015

@mmahalwy I never found a solution unfortunately and I don't understand the inner workings of omni auth and this lib to fix.
I switch to using omniauth-gplus

@gkopylov
Copy link
Contributor

@raldred I think it is not related to this gem. As you can see it is just a client side flow.

Unfortunately, when I posted solution above, I didn't take a close look into official google implementation and just experimented with code in the readme. So when you look at the official google readme https://developers.google.com/api-client-library/javascript/features/authentication#Authexample you can find that there are also two authorize actions with immediate false and immediate true.

@zquestz
Copy link
Owner

zquestz commented Jan 12, 2016

K after looking into this again, it seems clear the path forward. I am going to put in some fixes for the README. Will close once this is updated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants