Summarized using AI

Building modular, scalable web apps? of CORS!

Michael Bleigh • November 01, 2012 • Denver, Colorado • Talk

In this talk, Michael Bleigh presents an in-depth analysis of Cross Origin Resource Sharing (CORS) and its critical importance in developing modern web applications, particularly those using Ruby. He begins by introducing himself and provides background information about his experience with web technologies, drawing viewers into the relevance of CORS in the current development landscape.

The session goes on to cover several key points:

- Definition of CORS: CORS allows for cross-domain AJAX requests, which help to break the limitations of traditional browser security that restricts web pages from making requests to a different domain. This capability significantly enhances service-oriented architecture (SOA) implementations on the front end.
- Benefits of CORS: Michael explains that CORS facilitates building applications with a modular architecture, enabling developers to break down monolithic systems into smaller, independent modules that can be developed, tested, and scaled independently.
- Implementation Details: The speaker highlights how CORS works through a variety of HTTP headers that communicate whether a cross-domain request is permitted, outlining how browsers handle pre-flight requests for complex interactions. He discusses various security measures tied to CORS that protect servers from cross-domain attacks while allowing legitimate requests.
- Application Examples: CORS serves as the backbone for public APIs, allowing for easy integration of services without needing server-side orchestration. For example, he references how platforms like GitHub and Amazon S3 leverage CORS to allow users to create powerful applications that integrate multiple services seamlessly.
- Challenges and Considerations: The talk also touches on the complexities and potential drawbacks of implementing CORS, particularly in outdated browsers like Internet Explorer, as well as ensuring secure handling of sensitive information.
- Use Cases: Michael provides insight into building applications that utilize bearer tokens to manage user authentication across different service layers efficiently.

In conclusion, the session emphasizes the importance of CORS in contemporary web app development, arguing for its necessity in building scalable, secure, and flexible applications. He encourages developers to embrace CORS to enhance their projects, especially those involving public APIs, while considering the architectural implications of a service-oriented approach.

Building modular, scalable web apps? of CORS!
Michael Bleigh • Denver, Colorado • Talk

Date: November 01, 2012
Published: March 19, 2013
Announced: unknown

Cross Origin Resource Sharing (CORS) gives browsers the long-desired ability to make AJAX requests cross-domain. Even better, this functionality is dead simple to implement in Ruby. But while the implementation of CORS is simple, the implications are not. In this session learn about:

The many applications of CORS Using CORS to drive your application with a RESTful API Empowering 3rd party developers through registered CORS apps Implementing simple, secure user authentication for CORS apps Scale pieces of your app independently using CORS

RubyConf 2012

00:00:15.839 uh my name is Michael blle and I'm here today to talk to you about cross origin
00:00:21.680 resource sharing and why something that's really simple to implement really simple to use both on the Ruby and the
00:00:28.240 browser side um can actually have some pretty important ramifications for web
00:00:33.440 app development so a little bit of background on me um I am the co-founder and CEO of divot uh divot is an
00:00:40.840 interface builder for web applications so basically we're letting you drag and drop build uh using Twitter bootstrap
00:00:47.920 components for now but we're going to expand beyond that and sort of the difference from every other Dragon drop tool you've ever seen is that our prime
00:00:55.079 directive and our focus is on exporting clean code so you can actually you know use it
00:01:00.600 um you may have also seen some of my work um I'm also a fellow at in tridia
00:01:05.840 um I've worked on open source projects there for the last five years including omnio and grape um and yeah it's a ruby
00:01:13.479 consultancy fantastic people um so that's a little bit of background on me
00:01:19.520 um and if you'd like to follow along with the slides they are just it's HTML
00:01:25.040 so you can go follow m. github.com talk feel free all right so cross origin
00:01:32.759 resource sharing um what this basically is if you're not familiar actually let's
00:01:37.920 do a quick poll to get this out of the way um who's familiar with what cross origin resource sharing is
00:01:43.840 already okay good number of you who has used cross origin resource sharing in
00:01:49.680 either a side project or something production whatever okay um good to know so for
00:01:56.799 those of you who aren't familiar with it cross origin resource sharing is effectively cross domain Ajax so um you
00:02:03.960 know everyone's familiar with using XML HTTP requests in the browser in order to
00:02:10.080 request resources from the server without having to refresh the page well cross origin resource sharing lets you
00:02:16.040 do that same thing but rather than being restricted to the same domain that you're that the page loads on which has
00:02:22.760 been the traditional browser security case um now you're able to request from other domains um as long is on the
00:02:30.280 server side they're implementing this protocol um so you know you might you
00:02:36.080 might be familiar with Jon p as well where basically you make a request to remote endpoint that wraps it in a
00:02:42.519 callback function that is then is executed as JavaScript on your side and Json p is effectively um a hack way to
00:02:51.239 do cross doain Ajax um it only works for get requests you don't really have any
00:02:56.360 kind of error tracking error reporting custom headers there's lots of things you can't do with Json P that you can do
00:03:02.720 with Kors and like all good things Kors doesn't work that great in IE less than
00:03:08.720 10 um there is an ie equivalent of the cores called X domain request there are
00:03:17.200 also some various restrictions on how that works as opposed to the full cor standard um I'm not going to get into
00:03:23.840 that now but if you're building something that's for IE8 and N there are
00:03:29.000 a lot of things that I'm going to talk about that you'll be able to do some that you won't so dig into that a little bit
00:03:34.720 more so what is important about cores why does this cross domain Ajax actually
00:03:41.239 matter when it comes to building web applications um what it allows us to do really for the first time is we can
00:03:48.599 build an application that effectively implements service oriented architecture on the browser side so um there's
00:03:55.720 actually been a lot of talk about SOA at Ruby comp today and I think that's because more and more you know as we
00:04:01.760 mature as our applications get larger you realize that having this big monolithic application um just becomes
00:04:08.920 more and more unwieldy whether that's because your tests are taking longer and longer to run whether that's because you
00:04:14.400 have you know completely unrelated code and mass and just everything's getting out of control um you know the more you
00:04:21.440 can break your part your app apart the more you can turn it into small modules small independent things that work
00:04:28.040 together to give you the whole package uh the better off you are so to sort of
00:04:33.479 go over the oh and the other thing that I'm going to go to in a little while is that if you build a public API for your
00:04:41.199 application and you allow those developers to use cores um that can do
00:04:46.440 some really amazing things and um that's one of the things that I'd say if there's going to be a takeaway of go do
00:04:52.720 this if you have a public API for your application um figure out how you can make it work with cores because there's
00:04:58.240 some really awesome things but we'll get back to that in a little bit so um what
00:05:03.440 is Kors Kors is basically just a protocol where browsers and servers have
00:05:09.600 agreed on a set of headers that basically tell you whether or not um a
00:05:15.320 given domain is allowed to make Ajax requests um to it so basically how this
00:05:22.919 works is if you're doing a get request and it's just a vanilla get request you don't have any custom headers you need
00:05:28.240 to send or anything like that um your browser will just send that git request over to the server um and the server has
00:05:35.919 the option to respond with an um Access Control allow origin header um and the
00:05:43.639 access control allow origin header basically just says whether or not the
00:05:48.880 origin domain so if I'm on you know app. app.com and I'm making a request to
00:05:55.479 api.my app.com then api.my app.com has the opportunity to either approve or
00:06:02.840 deny that origin of app. app.com um for this request so basically in the
00:06:09.680 response headers there will either be um there will be Access Control allow origin and that can be a star which just
00:06:17.160 means any domain can make a request at any time or that'll be a specific origin
00:06:22.440 so if it's a specific origin that's either something that's going to be um just statically added to your server
00:06:28.520 somewhere in that you know I'm only ever going to allow requests from this one or you could dynamically compute what
00:06:34.520 that's going to be and send back a domain you know if it matches some wh list or some other uh specifications so
00:06:42.280 that's how it works for a get request for a post or put or delete or if you
00:06:47.360 need to send custom headers then what happens is it sends an options pre-flight request so what the browser
00:06:54.840 does is it says okay you're trying to make an Ajax request across domain and
00:07:00.120 it's not a vanilla get request you know I need to know more than just if this is allowed um because posting data to the
00:07:06.199 server could be dangerous in certain scenarios and the entire reason that browsers weren't allowed to do this
00:07:12.080 before and the entire reason that cores exist as a standard is to basically protect servers from Cross domain site
00:07:19.160 attacks so you know cross- site uh you know it's sort of a long similar principles as cross site forgery
00:07:26.120 protection and things like that by not allowing Ajax to go across domains you enable better security by default so if
00:07:33.639 you're making any request other than a vanilla get request then this options pre-flight request is sent first so the
00:07:40.479 browser before it actually sends the post or whatever you're trying to do um it'll send an options request that's
00:07:46.479 basically saying you know hey server I want to make this request is that okay
00:07:51.800 and the server will then respond with these various headers one of which is the access control allow origin which I
00:07:59.039 already talked aled about a little bit another is Access Control allow methods and this can be comma separated so if I
00:08:05.759 have the same endpoint and it can respond to get post put delete then I would add all of those to the access
00:08:12.280 control allow methods um in that options PreFlight request um there's Access Control expose
00:08:20.159 headers and allow headers so expose headers is saying these are the headers that I'm going to send that I want the
00:08:26.560 browser to be able to see um there are some basic headers that are that it's always allowed to see but if you have
00:08:32.080 any kind of custom headers that you're implementing things like that um maybe you're sending a an API rate limit along
00:08:37.519 as a header um you would need to add that to the exposed headers there's also the allowed headers which is this these
00:08:43.959 are the headers that the browser is allowed to send to the server so by the same token if I don't specify certain
00:08:50.880 headers that I'm expecting then the browser actually going to strip those headers off of the XML HTTP request
00:08:57.440 before it's sent so the server never actually sees that unless it gets the okay and again this is all done for
00:09:03.480 security sake um and this brings us back TOA in
00:09:08.519 the browser so this is sort of the really generic
00:09:14.680 idea of what is SOA um you know in a traditional application you might have a monolithic say it's a rails app doesn't
00:09:21.160 really matter what it is and that incorporates all of the different aspects of your application you know if
00:09:26.680 you have authentication user messaging and activity feed profiles you know a public API that developers can access if
00:09:33.320 that's all in a monolithic application then you know that's a single point that the browser is communicating with and
00:09:39.560 that may be a request response cycle or that may be through Ajax um you know
00:09:44.720 something more responsive like that uh but either way basically you're just communicating with one endpoint if you
00:09:50.880 take the service oriented approach then you take each of these components of your application so your authentication
00:09:56.920 your API your messaging system and you break those out into independent services and by independent services
00:10:03.720 that means um I mean it can mean a variety of things that can mean uh basically that they're logically
00:10:09.800 separate even if they're on the same Ser server so you're just basically separating all that logic these exist at
00:10:15.200 different endpoints um or they can be you know entirely different languages entirely different runtimes different
00:10:21.040 server infrastructure um different everything and what this does is it
00:10:26.240 gives you a ton of flexibility so the advantage of the advantages of a service oriented
00:10:31.800 approach is that you have scalability that works better because each of these individual Service Parts can be scaled
00:10:39.040 independently because theoretically they can all be on different infrastructure so if I have an application and 90% of
00:10:44.959 my requests have to do with user messaging and only 10% have to do with everything else it would be really nice
00:10:51.880 if I could rather than scaling up this you know giant monolithic app that maybe has a big memory footprint has a long
00:10:57.920 startup time what if I could just scale up the messaging part and have 10 times as many messaging servers running as I
00:11:04.040 have everything else so that's the basic idea behind the scalability of a service oriented design um reusability which I
00:11:12.399 completely misspelled um reusability is also important because as you build these as independent Services you might
00:11:19.480 come across say You're Building another application that can actually utilize the same service these Services um can
00:11:25.040 kind of take on a life of its own if you're familiar with Heroku add-ons um in a lot of ways once you start building
00:11:31.440 with a service oriented approach it's almost like you're creating your own add-ons for your application that do a
00:11:36.880 specific purpose that you need and if you have another application that has that same need down the road then you're
00:11:42.519 able to reuse that service without a lot of work without stripping out a bunch of code um again flexibility this just
00:11:49.639 allows you you know maybe I have parts of my application that are very non-concurrent real- time focused and so
00:11:56.200 I feel like node.js is a better fit for that part of the app but for my main application and my API I just want to
00:12:02.079 use Ruby um because I've already got code in there and it's really simple and everything like that so it allows you to
00:12:08.160 implement things in different architectures without sort of sacrificing or coming up with complex
00:12:13.760 schemes um fault tolerance so if I have part of my site go down if I have built
00:12:20.240 a service oriented architecture that's performing well it's potential that I only have a partial outage of my site
00:12:26.120 rather than it taking down the entire thing um and clean boundaries is just saying that because these services are
00:12:32.480 built independently they're able to communicate independently which means that there's always a clean separation
00:12:38.399 of responsibilities in your code so it sort of enfor it forces you to make harder and more important architectural
00:12:44.720 decisions earlier you have to really think about your app in terms of these modules and these Services rather than
00:12:51.360 just you know oh I'm going to slap some code in and we'll clean it up later so it kind of forces better coding practices a little more architectural
00:12:58.000 thinking on you up up front um which also is a bit of a disadvantage there is a bit of initial complexity to a service
00:13:04.920 oriented approach because now you're not just building one app you're not just using sort of the standard path You're
00:13:10.680 Building many applications you have to figure out how they're how and when they need to communicate with each other how
00:13:16.360 and when they need to communicate with the browser or whatever your central control point is so there is a little
00:13:21.639 bit more complexity with a server or with a service oriented architecture um cross- service communication can be
00:13:28.000 tricky um you know if I have a user's table on one server but I have another service that
00:13:34.839 needs to know some of that user information it can be a little bit tricky to figure out you know do I pull
00:13:40.240 that over and cash it for a while do I you know make a request each time to that service so figuring out the
00:13:46.160 boundaries of when and how much they should communicate with each other can be tricky um and the other thing is that
00:13:51.560 there's not really at least in the Ruby world and I'm not familiar with one that I think is particularly great um there's
00:13:58.000 not there's not sort of a framework that's like that's built from the ground up to let's make service oriented apps
00:14:04.440 you know this is an easy way to do it um there's lots of sort of tutorials there's some books out there that
00:14:09.639 describe how to do it um but there's nothing that's as easy as you know rails G controller users controller um that's
00:14:16.240 out there so those are some of the disadvantages but if you're building something that's more than a toy
00:14:21.720 application that you're expecting to spend months or even years maintaining um those disadvantages are really worth
00:14:28.720 the pain to get to the point where you're thinking architecturally you get that scal scalability and that
00:14:35.079 modularity so if you want to cheat a little bit and you want to sort of have a a service oriented architecture but
00:14:42.199 you don't really want to break it out into you know I'm going to run this on this server I'm going to run this on that server um you can use rack Cascades
00:14:49.759 so you know if you're familiar with rack all rails apps are rack apps all Sinatra apps are rack apps and so what you can
00:14:56.639 actually do is in your rack up file you can just run a rack Cascade of all of your applications so say you just have
00:15:03.360 you know a folder for each application and what rack Cascade does is if it get
00:15:08.440 if it encounters a 404 so it says resource not found then it just falls through and tries to call the next
00:15:13.759 application until something returns a non 404 response um or it returns a 404
00:15:18.920 response if it can't find one so that can sort of be a cheat where you're breaking it out into these Individual
00:15:24.040 Services but they're still all running in the same stack while you're sort of spinning things up
00:15:30.759 and my recommendation if you're going service oriented would be to keep things
00:15:35.839 lightweight um you know I'm a huge fan of Sinatra it's something that you can
00:15:41.519 just get in so quickly do a little bit of work you know everything's so clear um you know sort of a plug from my own
00:15:48.279 library but I also built grape which is a restful API framework um and these
00:15:53.800 apps tend to be a little bit easier to break apart than rails apps now that's not to say that there's not likely to be
00:15:59.920 a a place and a case for rails in your sort of service oriented architecture because you're probably going to end up
00:16:05.560 having maybe a core application that runs a lot of your logic um but not some
00:16:10.600 of these services and that might make sense as a rails app and I'm sure that people that you may have seen you know
00:16:16.839 there's the possibility of doing sort of one file rail apps and breaking that apart even more um but personally I
00:16:22.519 prefer things like Sinatra so as far as implementing cores in Ruby it's actually dead simple
00:16:29.720 because there's a gem for everything so use the rack cores gem so in your gem file you just add rack Das cores and
00:16:37.399 then it's a rack middleware so in your rack up file in an initializer for rails
00:16:42.680 you just use rack cores you have um you basically pass it in AOW block and
00:16:48.880 that's where you specify these are the origins that are okay um you can pass multiple arguments if you need to to
00:16:55.240 that one and then you can specify resources and on each resource in
00:17:00.839 addition to just specifying the path you can also specify methods which is going to give you that access control allow
00:17:07.160 methods you can supply headers expose so this is just a shorthand way to
00:17:12.959 automatically handle those options pre-flight requests um as a rack middleware so you just slip this into
00:17:20.480 your project and you're done so when I talked about if you have a public API looking to implementing cores um part of
00:17:26.240 the reason is because it's really really easy so let's dig in a little bit I built
00:17:32.720 just a really simple uh service oriented in the browser example so that we can go through both a few of the sort of
00:17:39.000 principles of what's going on and a few of the challenges you'll run into so here is my application it's very
00:17:46.960 simple obviously um and first thing I need to do is I need to sign
00:17:54.960 in oops
00:18:03.720 so now it's come back here and it asks for a status so hello
00:18:09.880 oops hello Ruby this is not my laptop and it
00:18:17.320 shows so I hit update it shows up over there um and that's all this application does so this is obviously very basic
00:18:24.720 this is not something that needs to be built in a service oriented manner but it was built in a service oriented
00:18:30.360 manner so that I could show you a few of the things that you might want to do um we're just going to go through the code on GitHub a little bit so the first
00:18:37.520 thing and this is one of the things that even though it's not terribly important I think is just really cool about what
00:18:43.360 you can do with cores and that is that the app itself is just static HTML there's no
00:18:51.080 server anything going on when you land on uh this page that's just static HTML so I could
00:18:58.280 serve that you know I could serve that using Apache I could serve that by just dumping everything onto Amazon
00:19:04.280 cloudfront and now I have it on a CDN so that gives you just a real simple power
00:19:10.080 I think to be able to serve your application that can do all of these amazing things as just static HTML and
00:19:16.400 not even worry about the server side um for your core application uh so that's
00:19:21.840 sort of the first thing and if you look basically we just have you know basic
00:19:27.440 HTML um and all of the logic takes place in application.js
00:19:35.039 oops there we go so taking a quick look at this um the
00:19:41.039 first thing that I'm doing here and this is a terrible hack that you'd want to do better in a real application uh but we
00:19:46.600 need to know the different services that we're talking to so in this case I've built two Services I've built an
00:19:52.000 authentication server yes oh yeah you bet let me is that better
00:19:59.600 all right cool um so I've built two services for this I've built an authentication Service and I've built a
00:20:06.240 stream service which is what allows me to publish and read from that stream you saw um so basically right now I'm just
00:20:12.440 setting up that these are the different these are the Ser these are the hosts of those services that I'm going to access
00:20:18.640 um so you need some way to do that usually but this is a bad way because I'm using conditional logic and
00:20:23.799 hard-coded things so don't do that um the next thing I'm doing here
00:20:29.200 is I'm setting an Ajax pre-filter so the authentication scheme that I'm using is
00:20:35.120 Loosely based on oo 2 type things in that we just have a bearer token that's generated and that Bearer token is given
00:20:41.799 to the browser and then stored locally on the browser so that it can make subsequent requests um to the stream
00:20:49.360 service excuse me using that using that
00:20:56.360 token so what I'm actually doing here is I'm using jQuery um I'm using an
00:21:02.360 Ajax pre-filter on jQuery to say if I have a token then I'm going to try to
00:21:07.880 make authenticated requests when I do Ajax requests so I'm going to add an authorization uh I'm going to add an
00:21:14.320 authorization header to my request that sends along this Bearer token so the next thing that we can look
00:21:21.919 at is what happens when the app launches and what happens here is that if you
00:21:28.039 look at the two specification um the way that you can send a bearer token to a
00:21:34.520 client side application so something where you can't trust the code you can't do have things like client Secrets
00:21:47.120 um so the way that that's dealt with at least somewhat is by passing The Token
00:21:52.159 in the location hash so because it's passed in the location hash if you're
00:21:57.440 not aware of this um anything after the pound sign in the URL is never actually
00:22:02.799 sent to the server so you want this token to be obis at least to a degree and by sending it in the location hash
00:22:09.000 that's not actually sent to the server when the request is made so you have a little bit more security there so all
00:22:14.600 I'm doing is I'm checking if there's a token when uh in the location hash when
00:22:19.760 we launch the application and if there is then I'm going to verify and make sure that that's a valid token otherwise
00:22:26.960 um we need otherwise we already have a token so I'm going to try attempt to fetch the stream of
00:22:33.600 updates um and now I think it'd probably be a good time to move over to our authentication app so that was our
00:22:41.279 static HTML browser app now our authentication app is just a onefile
00:22:47.000 synatra app that I wrote and here we're just setting up reddis
00:22:52.520 that's not a big deal um so the first thing you can see is all we're doing is
00:22:58.200 if you go to the root of this then we're going to authenticate using Twitter omnio um and that's just because that
00:23:05.400 was the simplest thing to implement so then we go through the normal omnio process if you're familiar with that but
00:23:11.880 basically it's going out making the ooth request coming back um and fetching user
00:23:17.080 inter user ID user information so that's what's happening in this call back phase is we're
00:23:23.039 just saving some user information and then we're going to generate that access token that I talked about so if you look
00:23:30.080 at this regenerate token method all we're doing is we're generating a URL
00:23:35.200 safe a URL safe token and we are saving that in reddis so that excuse me we can
00:23:43.000 look it up later and then like I said we redirect back to the apphost and include
00:23:49.640 in the hash the bearer token that we just had so that's really most of what
00:23:55.000 there is to this application the only other thing that we're doing is we have a verify method where we're
00:24:02.480 basically just checking to see if a token that's passed is associated with the user and if it is we're returning
00:24:08.559 information about that user and we'll get to that in just a second sorry about the
00:24:19.520 coughing so moving on to our stream application this again is just a oneline
00:24:25.679 Sinatra application um but this show you how you can sort of use services that talk to
00:24:32.080 each other um in general so what we're doing here is we have an authenticate
00:24:37.960 method so if you go down here I can either post to my activity stream or I can get activities from my
00:24:44.919 stream and what happens before any of that happens is I authenticate based on
00:24:50.080 the token the beer token is posted in is passed in um and so here what happens is
00:24:56.679 I'm actually making an HT TP request to that Au server to that verify endpoint
00:25:01.720 that I just talked about and I'm saying hey I just got this token but you know I'm not the Au server I'm the stream
00:25:07.080 server so can you tell me if it's okay and if the off server says yep that's a
00:25:12.559 valid token then the stream server can go ahead and complete the request and
00:25:17.799 Associate things with that token and that user ID otherwise it will send back
00:25:23.760 an unauthorized message so this is a way that Services both talk to to the browser or talk to the sort of central
00:25:30.240 controller but can also talk to each other when necessary um and so if we go back to I'm
00:25:38.480 not going to spend too much longer going through this the code is on GitHub um but just to go through sort of how the
00:25:44.520 posting works we'll go back to application.js you can
00:25:50.399 see um the verify token uh happens at the beginning when we log in just to
00:25:55.799 make sure that the token that we have stored is valid and then we have fet
00:26:01.360 fetch stream and post activity these are both just simple um and I I guess that's something that I didn't mention that I
00:26:07.360 definitely should um all of these requests all of these cores requests you do just like normal Ajax requests so on
00:26:14.480 the browser side you don't have to do anything different it will automatically do the options pre-flighting and
00:26:19.840 everything like that for you so if you're using jQuery if you're using whatever just do a normal XML HTTP
00:26:25.880 request and it'll go through um so long as the server is sending those appropriate
00:26:32.039 headers um so we can get activities we can post activities and then we're just
00:26:37.799 updating the interface so I mean that's pretty much it but what you can see is that this is really pretty simple to do
00:26:46.840 um and again I I really feel like it's something powerful where I have this application that's just static HTML and
00:26:53.720 I'm talking to this authentification service but what if I had you know a separate application but I'm using the
00:26:59.000 same user base well now that application can also talk to the authentication Service and I have this stream service
00:27:05.360 and maybe I have an email notification service that reads from the stream service to be able to push notifications
00:27:11.919 so once you start breaking things apart and modularizing them then you're able to just do a lot more sort of reusing
00:27:19.480 your code and thinking about things in terms of passing messages rather than just having this monolithic idea and
00:27:25.640 once you can do that in the browser then you just have the power to load you know if I have a messaging part
00:27:33.080 if you know if you imagine something like Facebook where you have messaging up here and and a user stream here and
00:27:39.240 you have you know a photos application and all of these things the browser can now coordinate all of those requests
00:27:45.240 they can all go to different services on different servers built with whatever the best architecture is for that and it
00:27:51.200 all just comes together nicely so um that's why I think that Kors is particularly powerful for sort of this
00:27:58.600 browser based service oriented architecture approach so I think that I just went
00:28:05.519 through all of that so we're going to go ahead and move on and talk about public apis that use cores and why that's
00:28:12.240 awesome and that is probably my favorite animated gif ever so what's so awesome about it first
00:28:19.799 of all it lowers the barrier to entry so if I build an application and I allow a
00:28:25.080 public chors API that means that the only thing thing that someone needs to do to be able to build an app that
00:28:31.039 leverages my API is have a text editor and a browser they don't need to run a server they can do this they can do this
00:28:37.840 locally they can run this from file slash so this just opens up a whole new
00:28:43.159 ability to build these super lightweight apps that do a lot more than you'd
00:28:48.279 expect they'd be able to it allows you to do mashups without servers so if you
00:28:53.720 imagine all of these you know mashup applications where it's you know let's take flicker data and mash it up with
00:28:59.960 Google Maps data um traditionally that was done by you
00:29:05.960 create a serers side application that accesses both of those apis it somehow mashes that data together and then
00:29:11.440 displays it back down to the browser in a way that's consumable but if I use
00:29:16.720 cores and I just build a website a web page that makes Kors requests out to the
00:29:21.760 flicker servers and makes Coors requests out to the Google Maps servers now I can do all of that processing on the client
00:29:27.760 side so I'm able to create powerful applications that combine multiple services that do all kinds of things
00:29:34.360 without ever needing to build some kind of custom server architecture um and that's also important because when you
00:29:39.880 think about things like Chrome extensions when you think about sort of simple downloadable Deployable HTML um
00:29:46.600 that's a really powerful Paradigm Services can become public apis
00:29:51.679 and what I mean by that is that you may build a service and at first you're using it internally but over time there
00:29:57.799 may be a greater use case for it than just your own internal use so you're actually able to expose that service to
00:30:04.640 the public without doing a lot of additional work um and finally it has
00:30:09.679 the same burden on you so you know the same requests are being made to your servers the only difference is that
00:30:14.760 you're sending these headers back but it's much less of a burden on your developer users who are building things
00:30:20.200 with your API so this is just something that I really like a lot um so as an example of
00:30:27.519 something that I've built that's sort of this Coors public API um divot alloy so
00:30:34.399 in building div shot we needed to the ability to have people edit CSS for their pages but I don't like editing CSS
00:30:41.279 I haven't done plain CSS in like four years so I wanted people to be able to use their favorite CSS
00:30:48.000 pre-processor um the problem with that is that there's multiple and there's valid reasons for using all of them so I
00:30:54.840 wanted to support SAS I wanted to support less I wanted to support stylus um and so I built alloy as a service to
00:31:02.080 allow us to do this for divot but then I realized that I had built a service that was really general purpose and useful so
00:31:10.320 um here's an example of it in divot so you know I'm in my application I have
00:31:16.120 this I'm going to give it a class let's say super class um now I'm going to edit some
00:31:23.880 stylus
00:31:33.480 so here's how we can utilize it in divot and that's great it allows me to do custom CSS on pages which is a feature
00:31:39.880 that lots of people wanted and now I was able to implement it but what it also allowed us to do is release it as an
00:31:46.480 open source public API so that anyone can use this so if you go to div shot.com alloy you can have this web API
00:31:53.440 for pre-processing CSS so whether I'm using stylus
00:31:58.760 it just compiles um I also built these bookmarklets that will actually let you click the bookmarklet and then click a
00:32:05.320 text area and then if you've written SAS or stylus in that text area it will just
00:32:11.399 convert the content of that into CSS so if you're using a website like Tumblr where it gives you the ability to have
00:32:17.480 custom CSS but you don't really want to write just CSS you want to use a pre-processor you can now use this bookmarklet instead and these were use
00:32:24.480 cases that came up because I built it in this service oriented way because I built alloy as a separate service rather
00:32:30.320 than as part of a monolith and so I think that it's just a really powerful Paradigm to allow you to
00:32:35.799 think about things that way um and famous examples the GitHub
00:32:43.679 API is 100% supporting of ches which is amazing um you can and you can see some
00:32:49.320 really awesome examples of that things that are just hosted as static HTML on GitHub that give you ways to browse your
00:32:57.039 issues browse you know everything on GitHub in some kind of intuitive or novel fashion and that's because GitHub
00:33:03.840 added this cor support in the last few months Amazon
00:33:09.639 added Coors support to S3 and that's a huge thing because now what you're able to do by leveraging S3 and cores you can
00:33:17.519 actually trigger file uploads that are uploading you know whether it's a 20K
00:33:22.960 jpeg or a 200 Meg movie you can offload all of that work on to Amazon servers
00:33:28.799 and it never even has to touch yours because by using cores the request goes straight to
00:33:34.080 Amazon so the file goes straight to Amazon and all you have to do is be able to deal with the response which is going
00:33:39.840 to be a URL of where it ended up being stored so that's what that's an example
00:33:44.960 of what I talked about where it takes the burden off of your users and doesn't add any burden to you because either way
00:33:50.720 this file was going to get uploaded S3 but in this case it was only uploaded S3 rather than uploaded to my server which
00:33:57.159 then got upload to S3 um you know one thing to think about
00:34:02.760 when you're implementing this on a public API is how to handle authentication like I said in the
00:34:08.399 browser you can't count on any kind of secrets so if you have a client secret something like that you can't count on
00:34:14.800 that being being kept um but you still want to be able to identify applications so that you can remove Bad actors things
00:34:21.560 like that um and GitHub solution for that is that they only allow cores
00:34:27.399 request from domains of registered ooth applications so if I register an ooth
00:34:33.639 application um that is em. github.com now I can actually make Coors requests
00:34:39.200 to the GitHub API from em. github.com because I registered that application
00:34:44.679 and I thought that that was a clever way to solve this problem it still lets you identify an application so it just looks
00:34:49.960 at the origin of the request and says oh this is coming from m. github.com so this is you know Michael's fancy GitHub
00:34:56.200 API application um so I just wanted to mention that as a good way to possibly handle
00:35:01.839 authentication if you do build this into a public API so now you know what you can do with
00:35:09.480 cores today um and you know this is it really is a simple technology that just
00:35:14.760 has a lot of applications and the question that I want to ask because I've only just started diving into this I
00:35:20.839 think there's a whole wealth of things that you can do that I haven't even thought of yet so I want to know what
00:35:26.040 will you do with cores tomorrow um so that's everything I'm happy to
00:35:32.000 take any questions you have and come talk to me afterwards or tomorrow or
00:35:37.200 whenever uh but thanks for your
00:35:46.960 time yeah in the GI example how is that any more secured would you still
00:35:53.680 have so it actually is less secure I mean it sort of is less secure and
00:36:00.200 there's nothing to be done about that so the reason that identifying applications is important is because if you're able
00:36:06.200 to identify the application then you're able to sort of say you know if this is
00:36:11.599 just someone that I don't know that's just created an application maybe that gets a certain permission level whereas if it's on our own servers that gets a
00:36:18.319 higher permission level because we know that it's from a trusted Source um so it just gives you the ability to identify
00:36:23.839 but um anything that's in the browser like that is sort of inherently less sec here because it can be in introspected
00:36:29.960 at any time um but as everyone found out when you know the Twitter Android keys were leaked and everything like that um
00:36:36.359 just because it's on a different platform doesn't mean it's necessarily more secure so yeah how do you do graceful
00:36:43.560 degradation for Internet Explorer um that is something that I don't worry
00:36:49.480 about myself because div shot is a tool for developers and it was something that I wanted to research for the talk but wasn't able to find sort of a quick
00:36:56.520 solution for so so I can't answer that 100% I know that there are some sort of shims out there in some libraries to um
00:37:05.119 massage cross domain XML HTTP requests into that X domain object um but I can't
00:37:10.839 tell you sort of the best way to do it yeah yui which I use at my office has a
00:37:19.839 module xdr which lets you use a native request or a flash request just by uh
00:37:26.000 configuration right um so you can that would work as an ID yeah so that's true
00:37:31.760 um so the sort of the way that people were doing cross domain requests before is that flash allows you to do it as
00:37:37.760 long as you have a I think it's domain policy. XML file something like that on
00:37:43.160 the server that allows you to do it so there's can be like a flash fallback similar to how there's a flash fallback
00:37:48.440 for websockets server side events things like that yeah and you found a paradigm for
00:37:54.359 integration testing with that kind of setup that you like um so for integration testing what's interested
00:38:00.880 about what's interesting is that because this is just standard xmlhttp requests
00:38:06.880 you can use um any of the like I I can't recall them off hand but there are
00:38:12.200 various libraries for basically mocking out xmlhttp requests and you can use those same things from the browser side
00:38:19.280 and then on the server side um you know you that would vary depending on how you're building it so if it's a Sinatra
00:38:24.760 application you can just use rack test to to hit it you if it's um you know in nodejs you'd use Jasmine or whatever you
00:38:31.920 use for nodejs um but I mean basically you test each of those independently and
00:38:37.000 then you can sort of stub out the boundaries as long as you agree on a communication protocol if that makes
00:38:43.680 sense yeah can you use cores to authenticate for other connections like
00:38:48.920 a web socket for instance um that is a good question I'm not 100% sure off the top of my head but
00:38:55.599 I believe so anybody else yeah I actually have a
00:39:01.079 question too okay would you ever actually do things allow cross policy
00:39:06.560 whatever as or you always specify a lot of examples at Asis that seems like
00:39:13.599 really um so in my opinion the asterisk is okay if
00:39:19.400 you're talking about usually something that's like a readon API or some kind of
00:39:24.839 transient data or something like that uh for anything where you're doing any kind
00:39:29.880 of real authentication something like that then yeah I think it's a better it's a much better policy to have you
00:39:35.560 know specific domains that you're allowing based on however you want to whitel list
00:39:42.800 that anybody else so what what about concerns on like exploiting these I just
00:39:48.640 can imagine like Theos and asteroids every every browser running attacks everywhere like so um I mean as far as
00:39:56.000 concerns you know it's really no less secure than any other for you know than
00:40:04.160 other kinds of you know cookie based session storage or things like that inherently there are risks when you put
00:40:11.280 data into the client but what you can do um is M mitigate those risks so in the little example application that I showed
00:40:18.560 um you know every time it loads up the application it verifies those tokens you can expire those tokens say every 10
00:40:24.880 minutes or something like that and require them to be refreshed and then you sort of minimize this window where
00:40:30.359 you know if I forget to log out someone can come back in use my token and exploit that to hit the API and do all
00:40:36.319 sorts of bad things um so I mean there are definitely things that you need to watch out for um but I think in general
00:40:43.800 it's it's not really less secure than other ways of communicating with the back end so long as you're sort of
00:40:49.680 cognizant of what you're doing and you're aware that you know you need to make sure that nothing that you consider
00:40:55.160 to be truly secret is ever shown to the browser
Explore all talks recorded at RubyConf 2012
+46