Your SlideShare is downloading. ×
0
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
Building @Anywhere (for TXJS)
Building @Anywhere (for TXJS)
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Building @Anywhere (for TXJS)

11,503

Published on

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

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

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide








































































  • Transcript

    • 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

    ×