Ember & SOA
Stumbling towards SOA
The story of CloudHDR
Outline
Context, Goals & Requirements
First Steps
Authenticaion
Leaving localhost
A bit about me
Jeremy Green
drummer, coder, entrepreneur, photographer, brewer
organizer of OkcRuby.org
@jagthedrummer
jeremy@octolabs.com http://www.octolabs.com/
These items are in chronological order.
I've been drumming much more than half my life.
Coding, just about half.
* next fragment *
Thanks to Jesse and Vance of okcjs for organizing Thunder Plains.
* next fragment *
I'm historically bad at Twitter, but trying to get better.
Contacting me through OctoLabs is more reliable.
CloudHDR
HDR Photo Processing Automation
HDR == High Dynamic Range
Why HDR?
You don't want this:
Goals & Reqs
My reqs might not be your reqs.
Understanding my reqs may help you understand my choices.
For different reqs you might make different choices.Goals & Reqs
- Small focused apps
- Single sign on/off
- Minimize code duplication
- Support a variety of app/service types
- Friendly to people and robots
Getting Started
- just started on localhost
- start an api on one port, and a 'client' on another
Getting Started
Start a local service
$ rails -p 3007
Configure Ember Data
// Configure Ember Data
App.ApplicationAdapter = DS.RESTAdapter.extend({
host: 'http://localhost:3007'
});
Better than hard coding
$ export FILE_SERVICE=http://localhost:3007/
// Configure Ember Data
App.ApplicationAdapter = DS.RESTAdapter.extend({
host: '<%= ENV["FILE_SERVICE"]%>',
namespace: 'api/v1'
});
Response Codes forJSON Requests
- Send a meaningful response code
- Don't just issue a redirect
Proceed as normal
- Routes
- Controllers
- Models
- Components
- Etc...
Congratulations!
You're "doing SOA"!
OAuth(2)
An open standard for delegated authorization
The request sequence looks something like this. OK, not really. I'll be speaking
at RailsConf next month about Service Oriented Authentication, which will go into more depth
about this part.
Ember + OAuth
Session Based Auth
Code for the Ember app
Retrieve some data
Handle authorization errors
Just get the current user when the app is ready
App = Ember.Application.create({
ready: function(){
var store = App.__container__.lookup('store:main');
var id = 'me?_=' + (new Date()).getTime();
store.find('user',id).then(function(user){
App.currentUser = user;
});
}
});
Custom 401 error handler
App.ApplicationAdapter = DS.RESTAdapter.extend({
ajaxError: function(jqXHR) {
var error = this._super(jqXHR);
if (jqXHR && jqXHR.status === 401) {
var newLocation = "http://files.cloudhdr.com/auth?return=";
newLocation += encodeURIComponent(document.location.toString());
document.location = newLocation;
} else {
return error;
}
}
});
Token Based Auth*
*I have not actually implemented this yet
Leaving localhost
Cross domain issues
Check the console
Luckily there is a tool that we can use to fix this problem.
CORS
Cross Origin Resource Sharing
Allows a site to tell browsers
that it is willing to
provide content/services to other sites
# Gemfile
gem "rack-cors", :require => "rack/cors"
# config/application.rb
config.middleware.use Rack::Cors do
allow do
origins(/http:\/\/localhost:\d*/,
/https:\/\/cloudhdr-\w*-octolabs\.fwd\.wf/,
/http:\/\/[\w-]*\.cloudhdr\.com/
)
resource '/api/v1/*',
:headers => :any,
:methods => [:get, :post, :put, :delete, :options]
end
end
Public/Open API
# config/application.rb
config.middleware.use Rack::Cors do
allow do
origins('*')
resource '/api/public/v1/*',
:headers => :any,
:methods => [:get]
end
end
Do NOT Do This!
# config/application.rb
config.middleware.use Rack::Cors do
allow do
origins('*')
resource '*',
:headers => :any,
:methods => [:get, :post, :put, :delete, :options]
end
end
Learn about Cross Site Scripting!
by default
jQuery
does not
send cookies
with AJAX requests
withCredentials to the rescue!
// send cookies with AJAX requests
$.ajaxPrefilter( function( options, originalOptions, jqXHR ) {
options.xhrFields = { withCredentials : true };
});
Wrap Up
- Understand your requirements
- Set up authentication
- Get ready for deployment
- Enjoy your SOA!