Friday, April 27, 2012

Good news, everyone! I upgraded the experimental hangoutiframer!

hangoutiframer.appspot.com provides a simple interface for you to automatically generate an .xml file that wraps an HTML file and puts it in an iframe in your Hangout. It's convenient for developers who have AJAX or Flash in their Hangout Apps, as it means your app is running on *your* website, not googleusercontent.com.

One of the new features in Hangout Apps is providing support for OAuth 2.0 access tokens. Once you create a Client ID for your Hangout App (a required step to release the app in public), users must give permission to your app to run. You can retrieve an access token from the gadget without further permissions or authentication.

Now, hangoutiframer can retrieve your access token, too! It also now supports appending data to the hangout URL for startup.

Sample Code

Try out our sample app!

http://plus.google.com/hangouts/_?gid=60353041584

You can find the code and instructions here:

http://code.google.com/p/hangout-experiments/source/browse/#git%2Foauth%2Fiframe

Passing data into a hangout iframer app

With today's upgrade, you can also pass in data from a startup URL, like so:

https://plus.google.com/hangouts/_?gid=60353041584&gd=SomeStartupData

and it will appear in your iframed Hangout app as a parameter to the iframe's URI. Give it a try!

Using OAuth 2.0 access tokens

Authentication and OAuth 2.0 can be complicated. For many apps, especially apps that have all of their state stored in the Hangouts API shared state, you probably don't need to worry about this. However, if you need to be sure someone is who they say they are, read on! You can (and should!) find out more about how OAuth 2.0 works at the Google OAuth 2.0 documentation.

A big reason to use an OAuth 2.0 access token in your hangout is to make verified actions on your server. That is, when a given participant makes some irreversible action, you want to know that it was really this participant, authorized for this app, to make that action.

One example might be looking at your cards in a card game---you don't want to put your cards in the Hangout shared state or a clever hacker can just look at them using the Chrome Javascript debugger! Instead, you will want each Hangout participant to talk to a server, and you want your server to be sure it's really that participant talking, not someone else in the Hangout who happens to know about this game. This is what an access token can provide.

If participants wants to see their cards, their running Hangout App can pass the OAuth 2.0 token to the server along with a request to be verified. Your server then can verify that it's them acting on behalf of your app using the validate token endpoint. Once the server has validated the token, it doesn't need to again for that particular Hangout instance. Your server then should send the client an app-specific authentication tokens for conversations between the Hangout App and your server.

The TokenInfo endpoint will return the valid scopes, the users G+ id, and the application that runs it. As a technical note, the 'audience' field of that token will contain a modified application id as it is running inside a gadget. The first part of the audience field should contain your app ID.

The tokens will expire, usually in about an hour. Right now, hangoutiframer doesn't support refreshing your access token when it expires, so it's good to validate the token early on in the client's relationship to the server.

As always...

Feel free to ask questions! hangoutiframer is still experimental, but it can get you started building Hangout Apps very quickly!

6 comments:

  1. This is great stuff :) thank you!

    But i have a problem when I try to use the following URL format to start hangouts from my site:

    http://plus.google.com/hangouts/_?gid=60353041584

    I use google authentication on my site too but when I'm logged in with multiple users the above URL always goes to the hangout as the default user. Which is not necessarily the user that is logged onto my site. This presented a small and easy to overcome issue with the sandbox but i can foresee a lot of other corner cases unless I can specify the correct user in the URL.

    I know that the user can be specified in an authuser parameter:

    http://plus.google.com/hangouts/_?gid=60353041584&authuser=1

    But this doesn't really help me as my application does not know the user index. Do you know anyway of getting the current user index associated with a logged in account or another way of explicitly specifying the user perhaps with the user ID (i tried passing the ID into the authuser parameter but got a 400 error - wasn't surprised)

    hope you can give me some pointers :)
    Pete

    ReplyDelete
    Replies
    1. Oh, and you can use Chrome profiles in place of multilogin to work around. I like to use those instead of multilogin so I can remember who I am!

      Delete
    2. Sorry, I should reply directly to this comment...

      Really short answer: That's not a supported URL option you should be using.

      Longer answer: Really, you shouldn't use that, and instead request stronger support for multilogin either at the product forum (so the Hangout itself intercepts multilogin before you enter the hangout) or for Hangouts API, at which point you can ask in the product forum and see if there's popular support, and/or open an issue there.

      However, if you're still curious about this sort of thing you could ask on the Federated Login API forum and see if anyone knows:

      https://groups.google.com/forum/?fromgroups#!forum/google-federated-login-api

      Generally, developer questions like this should be directed to:

      https://developers.google.com/+/discussions

      There are lots of people who read that forum who can weigh in on Hangout development. Don't get me wrong, my blog is the Taj Mahal of blogs, but the forum is a much higher-traffic place that can get you help faster. :-)

      Delete
    3. Thanks for the pointers :) I will indeed follow up on this over there

      Delete
  2. This comment has been removed by the author.

    ReplyDelete