0
@Anywhere
Helping Twitter escape from
twitter.com
<script src="http://platform.twitter.com/
anywhere.js?3e3222e3aed"></script>

<script>
  twttr.anywhere(1, function(T) {
 ...
twttr.anywhere(1, function(T) {
  T.bind('authComplete', function() {
    $('#current-user').html(
       "You are logged ...
Building @anywhere
Dan Webb (@danwrong / dan@twitter.com)




                                         TM
Building Cross Domain APIs
Dan Webb (@danwrong / dan@twitter.com)




                                         TM
‣   Secure
‣   Frictionless
‣   Unobtrusive
Overview
‣   Cross domain communication
‣   Building an RPC layer
‣   Wrapping the REST API
‣   Adding Authentication and ...
REST API: api.twitter.com
How do we
communicate with
api.twitter.com?
Same origin policy
api.twitter.com



XMLHTTPRequest
api.twitter.com


    ✖
XMLHTTPRequest
api.twitter.com



                   XMLHTTPRequest




                  http://api.twitter.com/
                       ...
api.twitter.com


                            ✔
                   XMLHTTPRequest




                  http://api.twitter...
api.twitter.com


                            ✔
                   XMLHTTPRequest


 Possible?
                  http://ap...
<iframe>
api.twitter.com




http://api.twitter.com/
      server.html
api.twitter.com




         ✖
http://api.twitter.com/
    example.html
HTML 5: postMessage
http://api.twitter.com/
server.postMessage(‘blah’, ...);
                              example.html
// from http://twaud.io...

var $iframe = $('#twitter_server'),
    server = $iframe[0].contentWindow;

server.postMessage...
// from http://api.twitter.com/server.html

window.parent.postMessage('Hello yourself!', '*');




// to http://twaud.io

...
Browser support for postMessage
‣   Firefox 3 and up
‣   Safari 4 and up
‣   Chrome
‣   Opera 9 and up
‣   IE 8 and up
Poor man’s postMessage
Flash LocalConnection
http://api.twitter.com/
    example.html
window.name
window.name = “{ some: ‘data’ }”




                         http://api.twitter.com/
                               serve...
var oldMessage;

function pollWindowName() {
  var message = window.name;
  if(message != oldMessage) {
    oldMessage = m...
Works in IE 6 & 7 but...
Limited message size
Problems when posting messages in quick succession
A lot less secure
Strings...
Implementing RPC
var publicMethods = {
   'account/verify_credentials': function(args, uuid) {
     $.ajax('/1/account/verify_credentials.j...
Sending the method call
var callbacks = [];

function remoteCall(method, args, callback) {
  var id;

    id = uuid++;
    callbacks[id] = callbac...
Returning the response
function returnResponse(e) {
  var call = e.data,
      method = call.method,
      args = call.args,
      uuid = call.uu...
var publicMethods = {
   'account/verify_credentials': function(args, uuid) {
     $.ajax('/1/account/verify_credentials.j...
Receiving the result
function receiveResult(e) {
  var result = e.data,
      uuid = result.uuid,
      response = result.response;

    callba...
Authentication &
Authorization
http://api.twitter.com/
remoteCall(‘method’,   [], ...);
                              example.html
Client                   User




         Authorization
@lukeshepard / sociallipstick.com
OAuth 2 (User Agent Flow)
http://wiki.oauth.net/OAuth-2.0
Client                       User

access_token=913-38h3ekjl2hc238e2238


             Authorization
How do we get the
access token to the client?
anywhere.js




SSL
http://oauth.twitter.com/2/authorize?
type=user_agent&
client_id=32ro23rfjd3&
redirect_uri=http://twaud.io/
http://oauth.twitter.com/2/authorize?
type=user_agent&
client_id=32ro23rfjd3&
redirect_uri=http://twaud.io/
http://oauth.twitter.com/2/authorize?
type=user_agent&
client_id=32ro23rfjd3&
redirect_uri=http://twaud.io/
Callback verification allows you to
prove that the site owns the client ID
anywhere.js
HTTP/1.1 302 Moved Temporarily
Date: Fri, 04 Jun 2010 19:59:41 GMT
Location: http://twaud.io/#oauth_access_token=913-...
GET / HTTP/1.1
Host: twaud.io
That’s magic!
Access token communicated back to browser securely.
No SSL support required for client site.
anywhere.js
var accessToken = parseTokenFromHash();

if (accessToken && window.opener && window.opener.setToken) {
  window.opener.set...
Couple of warnings	
‣   It’s secure, but not that secure
‣   Don’t store access tokens in a cookie (localStorage works)
‣ ...
Using the token to make
privileged calls
var callbacks = [];

function remoteCall(method, args, token, callback) {
  var id;

  id = uuid++;
  callbacks[id] = call...
var publicMethods = {
   'account/verify_credentials': function(args, uuid, token) {
     $.ajax('/1/account/verify_creden...
Overview
‣   Cross domain communication
‣   Building an RPC layer
‣   Wrapping the REST API
‣   Adding Authentication and ...
Questions?
@danwrong
@jointheflock
twitter.com/jobs
Building @Anywhere (for TXJS)
Building @Anywhere (for TXJS)
Building @Anywhere (for TXJS)
Building @Anywhere (for TXJS)
Building @Anywhere (for TXJS)
Building @Anywhere (for TXJS)
Building @Anywhere (for TXJS)
Upcoming SlideShare
Loading in...5
×

Building @Anywhere (for TXJS)

11,758

Published on

Published in: Technology
0 Comments
19 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
11,758
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
91
Comments
0
Likes
19
Embeds 0
No embeds

No notes for slide








































































  • Transcript of "Building @Anywhere (for TXJS)"

    1. 1. @Anywhere
    2. 2. Helping Twitter escape from twitter.com
    3. 3. <script src="http://platform.twitter.com/ anywhere.js?3e3222e3aed"></script> <script> twttr.anywhere(1, function(T) { T("#login").connectButton(); T.hovercards(); T("#comments").tweetBox(); T("#user-details").followButton('dsa'); }); </script>
    4. 4. twttr.anywhere(1, function(T) { T.bind('authComplete', function() { $('#current-user').html( "You are logged in as " + T.currentUser.screenName ); $('#follow-me').click(function() { T.User.find('danwrong').follow(function() { alert("Thanks, man, but I probably won't follow you back"); }); }); }); });
    5. 5. Building @anywhere Dan Webb (@danwrong / dan@twitter.com) TM
    6. 6. Building Cross Domain APIs Dan Webb (@danwrong / dan@twitter.com) TM
    7. 7. ‣ Secure ‣ Frictionless ‣ Unobtrusive
    8. 8. Overview ‣ Cross domain communication ‣ Building an RPC layer ‣ Wrapping the REST API ‣ Adding Authentication and Authorization
    9. 9. REST API: api.twitter.com
    10. 10. How do we communicate with api.twitter.com?
    11. 11. Same origin policy
    12. 12. api.twitter.com XMLHTTPRequest
    13. 13. api.twitter.com ✖ XMLHTTPRequest
    14. 14. api.twitter.com XMLHTTPRequest http://api.twitter.com/ server.html
    15. 15. api.twitter.com ✔ XMLHTTPRequest http://api.twitter.com/ server.html
    16. 16. api.twitter.com ✔ XMLHTTPRequest Possible? http://api.twitter.com/ server.html
    17. 17. <iframe>
    18. 18. api.twitter.com http://api.twitter.com/ server.html
    19. 19. api.twitter.com ✖ http://api.twitter.com/ example.html
    20. 20. HTML 5: postMessage
    21. 21. http://api.twitter.com/ server.postMessage(‘blah’, ...); example.html
    22. 22. // from http://twaud.io... var $iframe = $('#twitter_server'), server = $iframe[0].contentWindow; server.postMessage('Hello Twitter!', 'http://api.twitter.com/server.html'); // from http://api.twitter.com/server.html window.addEventListener('message', function(event) { var message = event.data; doSomethingAmazingWith(message); }, false);
    23. 23. // from http://api.twitter.com/server.html window.parent.postMessage('Hello yourself!', '*'); // to http://twaud.io window.addEventListener('message', function(event) { var reply = event.data; doSomethingAmazingWithReply(reply); }, false);
    24. 24. Browser support for postMessage ‣ Firefox 3 and up ‣ Safari 4 and up ‣ Chrome ‣ Opera 9 and up ‣ IE 8 and up
    25. 25. Poor man’s postMessage
    26. 26. Flash LocalConnection
    27. 27. http://api.twitter.com/ example.html
    28. 28. window.name
    29. 29. window.name = “{ some: ‘data’ }” http://api.twitter.com/ server.html
    30. 30. var oldMessage; function pollWindowName() { var message = window.name; if(message != oldMessage) { oldMessage = message; handle(message); } } setInterval(pollWindowName, 20);
    31. 31. Works in IE 6 & 7 but... Limited message size Problems when posting messages in quick succession A lot less secure Strings only (will need JSON)
    32. 32. Implementing RPC
    33. 33. var publicMethods = { 'account/verify_credentials': function(args, uuid) { $.ajax('/1/account/verify_credentials.json', { complete: function(data) { sendResponseToClient({ uuid: uuid, response: data }); } }); } };
    34. 34. Sending the method call
    35. 35. var callbacks = []; function remoteCall(method, args, callback) { var id; id = uuid++; callbacks[id] = callback; sendToServer({ uuid: id, method: method, args: args }); }
    36. 36. Returning the response
    37. 37. function returnResponse(e) { var call = e.data, method = call.method, args = call.args, uuid = call.uuid publicMethods[method].call(this, args, uuid); }
    38. 38. var publicMethods = { 'account/verify_credentials': function(args, uuid) { $.ajax('/1/account/verify_credentials.json', { complete: function(data) { sendResponseToClient({ uuid: uuid, response: data }); } }); } };
    39. 39. Receiving the result
    40. 40. function receiveResult(e) { var result = e.data, uuid = result.uuid, response = result.response; callbacks[uuid].call(this, response); }
    41. 41. Authentication & Authorization
    42. 42. http://api.twitter.com/ remoteCall(‘method’, [], ...); example.html
    43. 43. Client User Authorization
    44. 44. @lukeshepard / sociallipstick.com
    45. 45. OAuth 2 (User Agent Flow) http://wiki.oauth.net/OAuth-2.0
    46. 46. Client User access_token=913-38h3ekjl2hc238e2238 Authorization
    47. 47. How do we get the access token to the client?
    48. 48. anywhere.js SSL
    49. 49. http://oauth.twitter.com/2/authorize? type=user_agent& client_id=32ro23rfjd3& redirect_uri=http://twaud.io/
    50. 50. http://oauth.twitter.com/2/authorize? type=user_agent& client_id=32ro23rfjd3& redirect_uri=http://twaud.io/
    51. 51. http://oauth.twitter.com/2/authorize? type=user_agent& client_id=32ro23rfjd3& redirect_uri=http://twaud.io/
    52. 52. Callback verification allows you to prove that the site owns the client ID
    53. 53. anywhere.js
    54. 54. HTTP/1.1 302 Moved Temporarily Date: Fri, 04 Jun 2010 19:59:41 GMT Location: http://twaud.io/#oauth_access_token=913-...
    55. 55. GET / HTTP/1.1 Host: twaud.io
    56. 56. That’s magic! Access token communicated back to browser securely. No SSL support required for client site.
    57. 57. anywhere.js
    58. 58. var accessToken = parseTokenFromHash(); if (accessToken && window.opener && window.opener.setToken) { window.opener.setToken(accessToken); } self.close();
    59. 59. Couple of warnings ‣ It’s secure, but not that secure ‣ Don’t store access tokens in a cookie (localStorage works) ‣ It’s fairly easy for developers to accidentally leak tokens ‣ Make them expire after a very short amount of time ‣ Can use ‘immediate’ mode to refresh expired tokens
    60. 60. Using the token to make privileged calls
    61. 61. var callbacks = []; function remoteCall(method, args, token, callback) { var id; id = uuid++; callbacks[id] = callback; sendToServer({ uuid: id, method: method, args: args, token: token }); }
    62. 62. var publicMethods = { 'account/verify_credentials': function(args, uuid, token) { $.ajax('/1/account/verify_credentials.json', { beforeSend: function(xhr) { xhr.setRequestHeader( 'Authorization', 'Oauth oauth_access_token=' + token ); }, complete: function(data) { sendResponseToClient({ uuid: uuid, response: data }); } }); } };
    63. 63. Overview ‣ Cross domain communication ‣ Building an RPC layer ‣ Wrapping the REST API ‣ Adding Authentication and Authorization
    64. 64. Questions?
    65. 65. @danwrong @jointheflock twitter.com/jobs
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×