Live Coding: Rest APIs
in persona.js file. Adds an url to the model:
// persona.js
define(function(...){
// ... require dependencies
model.exports = Backbone.Model.extend({
url: "http://localhost:3000/auth/login",
initialize: function () {
}
})
})
To clarify: the localhost server is not the web server for the app. It’s an external service that the web app accesses. Talks a bit about Persona (in Firefox and Chrome, now discontinued)
Handshake process. After the handshake the user receives a secure hash. It works over simple http. Mozilla will unwrap this hash that contains personal information.
CORS: cross origin resource sharing
Works from IE8. Safe AJAX request between different domains. For example the authentication server is hosted on a different machine than the web server of the page.
Persona gives an id
on the navigator
object that contains personal information. It’s specific to your browser.
// persona.js
define(function(...){
// ... require dependencies
model.exports = Backbone.Model.extend({
url: "http://localhost:3000/auth/login",
initialize: function () {
// 1. ++++
navigator.id.watch({
onlogin: this.onlogin.bind(this),
onlogout: this.onlogout.bind(this)
})
},
// 2. ++++
onlogin: function(assertion){
var data = {
assertion: assertion
};
this.fetch({data: data});
},
onlogout: function () {
}
})
})
The onlogin and onlogout handlers will run whenever we attempt to authenticate with persona. Demonstrates (in Chrome browser) the authentification process with Mozilla.
After granting access with persona he can inspect the
comments.persona.toJSON()
in the browser console and gets back an object that contains some personal data e.g. his email address. The
assertion
in the above snippet is the cryptographic hash that is passed back from Mozilla Persona. Then, stil in
onlogin
we pass this personal data with fetch to the url we defined just above. This completes the “circle of authentication”.Then we need to override sync. Because we don’t care about the assertion we have been passed (by Mozilla Persona). We only care about the data we get back from the server.
// persona.js
define(function(...){
// ... require dependencies
model.exports = Backbone.Model.extend({
url: "http://localhost:3000/auth/login",
initialize: function () {
..
},
onlogin: function(assertion){
var data = {
assertion: assertion
};
this.fetch({data: data});
},
onlogout: function () { },
sync: function (method, model, options) {
var params = {
url: this.url,
type: 'post',
xhrFields: { withCredentials: true}
},
return $.ajax(_.extend(params, options));
}
})
})
We diverged from the path Backbone gives us (for fetch and sync) but we still have access to models and collections.This, redefined
sync
will be used by the this.fetch
call above (line #17).jQuery makes very CORS very easy for the browser.
We diverged from Backbone with
NOTE: The login and authentication lives inside a Backbone model.sync
above, but the data that comes back will automatically be stored in the Backbone model. So we get change events, etc.We can also test it in isolation.