-
Notifications
You must be signed in to change notification settings - Fork 240
Requiring authentication
Use a before-filter to require authentication for all controller actions in your app.
You can use the except
property to exempt certain actions from the filter and the only
property to require it only for certain actions.
If you're going to do any sort of I/O during the filter, you have to flag it with async: true
, and call a complete
callback when you're done to allow the action to run after the filter.
Example
This example requires the requireAuthorization
function to run before all actions except the "authorize" and "healthcheck" actions. It looks for a session with an OAuth access token, and if it doesn't find one send the user into an OAuth authentication flow.
This is just an example, but the OAuth flow would be similar for any provider who does OAuth2.
/**
@description Asynchronous before-filter that ensures a user
has OAuth2-authorized the app, and has a valid access-token.
*/
var requireAuthorization = function (complete) {
var self = this
, opts
, config = geddy.config
, app = config.clientApp
, code
, req
, url;
// If there's no session with an access-token
if (!this.session.get('accessToken')) {
code = this.params.code;
// Have code, get access_token
if (code) {
url = config.oauthProvider +
'/oauth2/access_token.json?client_id=' + app.id +
'&client_secret=' + app.secret + '&code=' + code;
// Grab the OAuth2 access-token
geddy.request({url: url}, function (err, data) {
var token = data.access_token.token;
// Prevent session-fixation
self.session.reset();
// Save the access-token for all API-requests
self.session.set('accessToken', token);
self.redirect('/');
complete();
});
}
// No code, do OAuth2 hokey-pokey
else {
this.redirect('/authorize');
complete();
}
}
// We have a session with an access-token
else {
// Do any other stuff you might need to do before
// running the action (e.g., do API calls to set up
// user-data)
complete();
}
};
var Application = function () {
this.protectFromForgery();
this.before(requireAuthorization, {
except: ['authorize', 'healthcheck']
, async: true
});
};
exports.Application = Application;
(The protectFromForgery
method prevents cross-site requests for PUT/POST/DELETE. To use this feature, you have to run the geddy secret
command-line command to generate a secret for your app.)
Below is an example of a Main controller that could implement the '/authorize' endpoint that routes your users through the OAuth flow of your chosen provider:
var Main = function () {
this.index = function (req, resp, params) {
// Do main app stuff
};
this.authorize = function (req, resp, params) {
var config = geddy.config
, app = config.clientApp
, redir = encodeURIComponent(config.hostname + app.callbackURL);
this.redirect(config.oauthProvider + '/dialog/oauth?client_id=' +
app.id + '&redirect_uri=' + redir);
};
this.healthcheck = function () {
this.respond('ok');
};
};
exports.Main = Main;