Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Building @Anywhere (for TXJS)

19,089 views

Published on

Published in: Technology
  • Be the first to comment

Building @Anywhere (for TXJS)

  1. @Anywhere
  2. Helping Twitter escape from twitter.com
  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. 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. Building @anywhere Dan Webb (@danwrong / dan@twitter.com) TM
  6. Building Cross Domain APIs Dan Webb (@danwrong / dan@twitter.com) TM
  7. ‣ Secure ‣ Frictionless ‣ Unobtrusive
  8. Overview ‣ Cross domain communication ‣ Building an RPC layer ‣ Wrapping the REST API ‣ Adding Authentication and Authorization
  9. REST API: api.twitter.com
  10. How do we communicate with api.twitter.com?
  11. Same origin policy
  12. api.twitter.com XMLHTTPRequest
  13. api.twitter.com ✖ XMLHTTPRequest
  14. api.twitter.com XMLHTTPRequest http://api.twitter.com/ server.html
  15. api.twitter.com ✔ XMLHTTPRequest http://api.twitter.com/ server.html
  16. api.twitter.com ✔ XMLHTTPRequest Possible? http://api.twitter.com/ server.html
  17. <iframe>
  18. api.twitter.com http://api.twitter.com/ server.html
  19. api.twitter.com ✖ http://api.twitter.com/ example.html
  20. HTML 5: postMessage
  21. http://api.twitter.com/ server.postMessage(‘blah’, ...); example.html
  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. // 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. Browser support for postMessage ‣ Firefox 3 and up ‣ Safari 4 and up ‣ Chrome ‣ Opera 9 and up ‣ IE 8 and up
  25. Poor man’s postMessage
  26. Flash LocalConnection
  27. http://api.twitter.com/ example.html
  28. window.name
  29. window.name = “{ some: ‘data’ }” http://api.twitter.com/ server.html
  30. var oldMessage; function pollWindowName() { var message = window.name; if(message != oldMessage) { oldMessage = message; handle(message); } } setInterval(pollWindowName, 20);
  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. Implementing RPC
  33. var publicMethods = { 'account/verify_credentials': function(args, uuid) { $.ajax('/1/account/verify_credentials.json', { complete: function(data) { sendResponseToClient({ uuid: uuid, response: data }); } }); } };
  34. Sending the method call
  35. var callbacks = []; function remoteCall(method, args, callback) { var id; id = uuid++; callbacks[id] = callback; sendToServer({ uuid: id, method: method, args: args }); }
  36. Returning the response
  37. function returnResponse(e) { var call = e.data, method = call.method, args = call.args, uuid = call.uuid publicMethods[method].call(this, args, uuid); }
  38. var publicMethods = { 'account/verify_credentials': function(args, uuid) { $.ajax('/1/account/verify_credentials.json', { complete: function(data) { sendResponseToClient({ uuid: uuid, response: data }); } }); } };
  39. Receiving the result
  40. function receiveResult(e) { var result = e.data, uuid = result.uuid, response = result.response; callbacks[uuid].call(this, response); }
  41. Authentication & Authorization
  42. http://api.twitter.com/ remoteCall(‘method’, [], ...); example.html
  43. Client User Authorization
  44. @lukeshepard / sociallipstick.com
  45. OAuth 2 (User Agent Flow) http://wiki.oauth.net/OAuth-2.0
  46. Client User access_token=913-38h3ekjl2hc238e2238 Authorization
  47. How do we get the access token to the client?
  48. anywhere.js SSL
  49. http://oauth.twitter.com/2/authorize? type=user_agent& client_id=32ro23rfjd3& redirect_uri=http://twaud.io/
  50. http://oauth.twitter.com/2/authorize? type=user_agent& client_id=32ro23rfjd3& redirect_uri=http://twaud.io/
  51. http://oauth.twitter.com/2/authorize? type=user_agent& client_id=32ro23rfjd3& redirect_uri=http://twaud.io/
  52. Callback verification allows you to prove that the site owns the client ID
  53. anywhere.js
  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. GET / HTTP/1.1 Host: twaud.io
  56. That’s magic! Access token communicated back to browser securely. No SSL support required for client site.
  57. anywhere.js
  58. var accessToken = parseTokenFromHash(); if (accessToken && window.opener && window.opener.setToken) { window.opener.setToken(accessToken); } self.close();
  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. Using the token to make privileged calls
  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. 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. Overview ‣ Cross domain communication ‣ Building an RPC layer ‣ Wrapping the REST API ‣ Adding Authentication and Authorization
  64. Questions?
  65. @danwrong @jointheflock twitter.com/jobs

×