OAuth.JS is a Javascript library used to easily request secured OAuth 2.0 Web Services.
The design of the library is largely inspired by the Facebook Javascript SDK and provides you similar methods, but the difference is that the called Web Services are not Facebook one's but your own Web Services.
OAuth.JS is specifically designed to work with RIA, SPA and HTML5 web / mobile applications, it provides the following features :
- Access and refresh token retrieval
- Automatic and transparent Access and Refresh token reniewal
- Automatic URL modifications to add an
access_token=xxxxxxxx
parameter in all your Web Service URLs - Access and refresh token storage on client side
- Credentials storage on client side
- JQuery, Backbone and Angular AJAX method overwritings to transparently request your secured OAuth 2.0 Web Services using your favorite framework
The easiest way to use the library is to pull it with Bower by adding the following dependency
inside your bower.json
file.
{
"devDependencies": {
"oauth.js" : "~0.1",
}
}
Using OAuth.JS is very easy and is done in 2 steps :
- First initialize the OAuth.JS client using the
OAuth.init(opts)
method (the nameinit
has been choosen to be similar to Facebook'sFB.init(opts)
method). - Call your secured Web Services using the
secured
additional parameter.
Detailed configuration and usage is described in the following sub sections.
When your application starts initialize the OAuth.JS client using the following peace of code.
OAuth.init(
{
clientId : 'my-app'
tokenEndpoint : 'https://myserver.com/token',
loginFn : function(credentialsPromise) { ...
// Open a login view and resolve the promise with the provided credentials
// Then OAuth.JS will do what's necessary to get an OAuth 2.0 Access Token automatically
},
parseErrorFn : function(xMLHttpRequest) {
// Parse errors returned from server side to know if they must imply OAuth 2.0 Access Token reniewal or
// refresh
}
}
);
The OAuth.JS client requires 4 parameters described in the following sub-sections.
The OAuth 2.0 Client Credentials client_id
parameter to be sent by the OAuth.JS client to get new Access Tokens.
The absolute URL to your OAuth 2.0 token endpoint.
The loginFn
function is used to display a login dialog or page to the user. We could compare this login modal dialog
to the Facebook Javascript SDK Login Modal Dialog. But with OAuth.JS you create your own Login Modal Dialog, then the
library will automatically call it when its necessary.
The loginFn
function will be called each time the OAuth.JS client detects it cannot use a valid OAuth 2.0 Access Token
.
This could appear in the following situations :
- Your server returned an error and the parsing of this error indicates that the OAuth 2.0 Access Token received is invalid.
- The OAuth.JS client cannot use or find a valid cached OAuth 2.0 Access Token.
The loginFn(credentialsPromise)
function takes only 1 parameter which we call a credentials promise. This credentials
promise must be called / resolved when your user provides its credentials in your Login Modal Box.
The CredentialsPromise
object is an object you have to keep while OAuth.JS did not return a successful login response.
This object has only one method sendCredentials
.
The sendCredentials
method is used to send credentials entered by your users to your OAuth 2.0 server, this method can
be called with the following parameters :
credentials
: An object which describes the user credentials to send on server side.cb
: A callback function called by the OAuth.JS client after credentials have been provided and sent to the server and a response has been received.opts
: Additional options used to configure the login behavior.
Here is a sample function (we suppose our application provides a simple Login Modal) :
function(credentialsPromise) {
// Show our custom Login Modal dialog and pass it the OAuth.JS Credentials Promise object
showLoginModal(new LoginModal({ credentialsPromise : credentialsPromise }));
}
Our Login Modal could contain the following code.
{
initialize : function(options) {
this._credentialsPromise = options.credentialsPromise;
},
_onLoginButtonClick : function(clickEvent) {
// Change the style of our form while OAuth.JS is trying to get an OAuth 2.0 Access Token
this.disableForm();
this.showWaitingIndicator();
// We transmit the credentials to OAuth.JS to let it get a new OAuth 2.0 Access Token with those credentials
this._credentialsPromise.sendCredentials(
{
// Indicates to OAuth.JS which OAuth 2.0 grant type to use to get an OAuth 2.0 Access Token
'grand_type' : 'password',
username : $('#username').val(),
password : $('#password').val()
},
$.proxy(this._afterLogin, this)
);
},
_afterLogin : function(response) {
if(response.status === 'connected') {
// Force the view displayed before the Login Modal Box to be refreshed
window.location.hash = window.location.hash + '?random=' + Math.random();
} else {
this.showError('Login failed !');
}
}
}
Callback function called by the OAuth.JS client when an error is returned from your Web Services. The purpose of this function is to decode the error payload received and indicate to the OAuth.JS client if the error received should trigger an OAuth 2.0 token refresh or reniewal.
The first time you application starts and your OAuth.JS client is configured nothing has been done on client side to indicate to OAuth.JS how to request your secured Web Services.
To work correctly OAuth.JS must have an OAuth 2.0 Access Token available, to retrieve a first OAuth 2.0 Access Token you have to ask your users to login into your app. After a first successful login an OAuth 2.0 Access Token is retrieved and cached on client side, this cached OAuth 2.0 Access Token is then transparently used by OAuth.JS to keep a secured connection opened between your app and your server (automatic Access Token refresh).
OAuth.JS provided the OAuth.login(cb)
function to check if it has a valid OAuth 2.0 Access Token (please note thate
the OAuth.login(cb)
function is very similar to the Facebook Javascript SDK FB.login(cb)
function, but instead of
opening a Facebook login modal box OAuth.JS will open your own login modal or view). If the OAuth.login(cb)
function
detects that no OAuth 2.0 Access Token is available or the one available is invalid then it will automatically open your
loginFn
callback function. If OAuth.JS detects that a valid OAuth 2.0 Access Token is available it calls the login
callback directly without requesting your server.
Here is a sample.
OAuth.login(function(response) {
// Here we can be sure OAuth.JS has a valid OAuth 2.0 Access Token, so we can requet a secured Web Service
// In general each time you plan to display a view which requires data get from a secured Web Service you have to
// wrap you view opening code inside the login function
Backbone.Radio.channel('app-view').command('show-center-view', new MyAccountView());
});
If your OAuth.JS client is correctly initialized the
XMLHttpRequest
object in use in your
application has been overwritten to manage OAuth 2.0 transparently.
When you request your server you have now 2 choices :
- You want to request a publicly available resource, in this case OAuth.JS do not have to do anything and the request should work normally.
- You want to request a Web Service secured using OAuth 2.0, in this case you have to provided a special
secured
parameter to your AJAX request function.
The following sub sections shows several request scenarios using multiple frameworks.
// Public request
var req = new XMLHttpRequest();
req.open('GET', 'https://myserver.com/rest/user_accounts/10', true);
req.onreadystatechange = function (event) { ... }
req.send(null);
// Secured request
var req = new XMLHttpRequest();
req.openSecured('GET', 'https://myserver.com/rest/user_accounts/10', true);
req.onreadystatechange = function (event) { ... }
req.send(null);
// Public request
$.ajax(
{
url : 'https://myserver.com/rest/user_accounts/10',
success : function(data, textStatus, jqXHR) { ... },
error : function(jqXHR, textStatus, errorThrown) { ... }
}
);
// Secured request (add a special 'secured' parameter)
$.ajax(
{
url : 'https://myserver.com/rest/user_accounts/10',
success : function(data, textStatus, jqXHR) { ... },
error : function(jqXHR, textStatus, errorThrown) { ... },
secured : true
}
);
// Public request
new User({id : 10}).fetch(
{
success : function(model, response, options) { ... },
error : function(model, response, options) { ... }
}
);
// Secured request (add the special 'secured' parameter)
new User({id : 10, secured : true}).fetch(
{
success : function(model, response, options) { ... },
error : function(model, response, options) { ... },
secured : true
}
);
// Public request
$http.get('https://myserver.com/rest/user_accounts/10').
success(function(data, status, headers, config) { ... }).
error(function(data, status, headers, config) { ... });
// Secured request (add a special 'secured' parameter)
$http.get('https://myserver.com/rest/user_accounts/10', { secured : true }).
success(function(data, status, headers, config) { ... }).
error(function(data, status, headers, config) { ... });
The following schema shows how the library works to automatically inject an access_token
parameter in all URLs used to
request your Web Services.
On this schema we suppose we've initialized an OAuth.JS request manager. We want to get a protected list of users. As our server also acts as an OAuth 2.0 authorization server we have to provide a valid OAuth 2.0 Access Token to autorize our request. OAuth.JS allows you to request your Web Services as if they where not secured, under the cover the library will automatically add whats necessary to authorize you requests.
{
getCredentials : function(credentialsPromise) {
// Open a popup and ask for user credentials...
// Resolving the credentials promise will instruct OAuth.js to get a new OAuth 2.0 Access Token using the
// configured token end point
credentialsPromise.resolve(
{
grant_type : 'password',
username : 'john',
password : 'doe'
}
);
}
}
{
getCredentials : function(credentialsPromise) {
// Open a popup and login the use with Facebook, the retrieve the Facebook Auth response
// Resolving the credentials promise will instruct OAuth.js to get a new OAuth 2.0 Access Token using the
// configured token end point
credentialsPromise.resolve(
{
grant_type : 'oauthjs_facebook',
facebookAuthResponse : facebookAuthResponse
}
);
}
}
OAuth.JS has been created to easily request your secured OAuth 2.0 Web Services inside RIA, SPA and mobile applications. In this context we often use the Resource Owner Password Credentials Grant to get an OAuth 2.0 Access Token.
So for now the Resource Owner Password Credentials Grant is the only OAuth 2.0 Authorization Grant supported in OAuth.JS.