function Authenticator() { this._key = 'passport'; this._strategies = {}; this._serializers = []; this._deserializers = []; this._infoTransformers = []; this._framework = null; this._userProperty = 'user'; this.init(); }
n/a
function Authenticator() { this._key = 'passport'; this._strategies = {}; this._serializers = []; this._deserializers = []; this._infoTransformers = []; this._framework = null; this._userProperty = 'user'; this.init(); }
n/a
function Strategy() { }
n/a
function SessionStrategy() { Strategy.call(this); this.name = 'session'; }
n/a
function Authenticator() { this._key = 'passport'; this._strategies = {}; this._serializers = []; this._deserializers = []; this._infoTransformers = []; this._framework = null; this._userProperty = 'user'; this.init(); }
n/a
_strategy = function (name) { return this._strategies[name]; }
...
var layer = name[i];
// If no more strategies exist in the chain, authentication has failed.
if (!layer) { return allFailed(); }
// Get the strategy, which will be used as prototype from which to create
// a new instance. Action functions will then be bound to the strategy
// within the context of the HTTP request/response pair.
var prototype = passport._strategy(layer);
if (!prototype) { return next(new Error('Unknown authentication strategy "' + layer + '"')); }
var strategy = Object.create(prototype);
// ----- BEGIN STRATEGY AUGMENTATION -----
// Augment the new strategy instance with action functions. These action
...
authenticate = function (strategy, options, callback) { return this._framework.authenticate(this, strategy, options, callback); }
...
/**
* Middleware that will authenticate a request using the given `strategy` name,
* with optional `options` and `callback`.
*
* Examples:
*
* passport.authenticate('local', { successRedirect: '/', failureRedirect
: '/login' })(req, res);
*
* passport.authenticate('local', function(err, user) {
* if (!user) { return res.redirect('/login'); }
* res.end('Authenticated!');
* })(req, res);
*
* passport.authenticate('basic', { session: false })(req, res);
...
authorize = function (strategy, options, callback) { options = options || {}; options.assignProperty = 'account'; var fn = this._framework.authorize || this._framework.authenticate; return fn(this, strategy, options, callback); }
...
* `req.user` will be unaffected.
*
* This function is particularly useful when connecting third-party accounts
* to the local account of a user that is currently authenticated.
*
* Examples:
*
* passport.authorize('twitter-authz', { failureRedirect: '/account
' });
*
* @param {String} strategy
* @param {Object} options
* @return {Function} middleware
* @api public
*/
Authenticator.prototype.authorize = function(strategy, options, callback) {
...
deserializeUser = function (fn, req, done) { if (typeof fn === 'function') { return this._deserializers.push(fn); } // private implementation that traverses the chain of deserializers, // attempting to deserialize a user var obj = fn; // For backwards compatibility if (typeof req === 'function') { done = req; req = undefined; } var stack = this._deserializers; (function pass(i, err, user) { // deserializers use 'pass' as an error to skip processing if ('pass' === err) { err = undefined; } // an error or deserialized user was obtained, done if (err || user) { return done(err, user); } // a valid user existed when establishing the session, but that user has // since been removed if (user === null || user === false) { return done(null, false); } var layer = stack[i]; if (!layer) { return done(new Error('Failed to deserialize user out of session')); } function deserialized(e, u) { pass(i + 1, e, u); } try { var arity = layer.length; if (arity == 3) { layer(req, obj, deserialized); } else { layer(obj, deserialized); } } catch(e) { return done(e); } })(0); }
...
};
/**
* Registers a function used to deserialize user objects out of the session.
*
* Examples:
*
* passport.deserializeUser(function(id, done) {
* User.findById(id, function (err, user) {
* done(err, user);
* });
* });
*
* @api public
*/
...
framework = function (fw) { this._framework = fw; return this; }
...
/**
* Initialize authenticator.
*
* @api protected
*/
Authenticator.prototype.init = function() {
this.framework(require('./framework/connect')());
this.use(new SessionStrategy());
};
/**
* Utilize the given `strategy` with optional `name`, overridding the strategy's
* default name.
*
...
init = function () { this.framework(require('./framework/connect')()); this.use(new SessionStrategy()); }
...
this._strategies = {};
this._serializers = [];
this._deserializers = [];
this._infoTransformers = [];
this._framework = null;
this._userProperty = 'user';
this.init();
}
/**
* Initialize authenticator.
*
* @api protected
*/
...
initialize = function (options) { options = options || {}; this._userProperty = options.userProperty || 'user'; return this._framework.initialize(this, options); }
...
* Passport to operate.
*
* Options:
* - `userProperty` Property to set on `req` upon login, defaults to _user_
*
* Examples:
*
* app.use(passport.initialize());
*
* app.use(passport.initialize({ userProperty: 'currentUser' }));
*
* @param {Object} options
* @return {Function} middleware
* @api public
*/
...
serializeUser = function (fn, req, done) { if (typeof fn === 'function') { return this._serializers.push(fn); } // private implementation that traverses the chain of serializers, attempting // to serialize a user var user = fn; // For backwards compatibility if (typeof req === 'function') { done = req; req = undefined; } var stack = this._serializers; (function pass(i, err, obj) { // serializers use 'pass' as an error to skip processing if ('pass' === err) { err = undefined; } // an error or serialized object was obtained, done if (err || obj || obj === 0) { return done(err, obj); } var layer = stack[i]; if (!layer) { return done(new Error('Failed to serialize user into session')); } function serialized(e, o) { pass(i + 1, e, o); } try { var arity = layer.length; if (arity == 3) { layer(req, user, serialized); } else { layer(user, serialized); } } catch(e) { return done(e); } })(0); }
...
};
/**
* Registers a function used to serialize user objects into the session.
*
* Examples:
*
* passport.serializeUser(function(user, done) {
* done(null, user.id);
* });
*
* @api public
*/
Authenticator.prototype.serializeUser = function(fn, req, done) {
if (typeof fn === 'function') {
...
session = function (options) { return this.authenticate('session', options); }
...
* However, as a general rule, most web applications will make use of sessions.
* An exception to this rule would be an API server, which expects each HTTP
* request to provide credentials in an Authorization header.
*
* Examples:
*
* app.use(connect.cookieParser());
* app.use(connect.session({ secret: 'keyboard cat' }));
* app.use(passport.initialize());
* app.use(passport.session());
*
* Options:
* - `pauseStream` Pause the request stream before deserializing the user
* object from the session. Defaults to _false_. Should
* be set to true in cases where middleware consuming the
...
transformAuthInfo = function (fn, req, done) { if (typeof fn === 'function') { return this._infoTransformers.push(fn); } // private implementation that traverses the chain of transformers, // attempting to transform auth info var info = fn; // For backwards compatibility if (typeof req === 'function') { done = req; req = undefined; } var stack = this._infoTransformers; (function pass(i, err, tinfo) { // transformers use 'pass' as an error to skip processing if ('pass' === err) { err = undefined; } // an error or transformed info was obtained, done if (err || tinfo) { return done(err, tinfo); } var layer = stack[i]; if (!layer) { // if no transformers are registered (or they all pass), the default // behavior is to use the un-transformed info as-is return done(null, info); } function transformed(e, t) { pass(i + 1, e, t); } try { var arity = layer.length; if (arity == 1) { // sync var t = layer(info); transformed(null, t); } else if (arity == 3) { layer(req, info, transformed); } else { layer(info, transformed); } } catch(e) { return done(e); } })(0); }
...
* allowing the full set of client properties to be convieniently accessed.
*
* If no transforms are registered, `info` supplied by the strategy will be left
* unmodified.
*
* Examples:
*
* passport.transformAuthInfo(function(info, done) {
* Client.findById(info.clientID, function (err, client) {
* info.client = client;
* done(err, info);
* });
* });
*
* @api public
...
unuse = function (name) { delete this._strategies[name]; return this; }
...
*
* However, in certain situations, applications may need dynamically configure
* and de-configure authentication strategies. The `use()`/`unuse()`
* combination satisfies these scenarios.
*
* Examples:
*
* passport.unuse('legacy-api');
*
* @param {String} name
* @return {Authenticator} for chaining
* @api public
*/
Authenticator.prototype.unuse = function(name) {
delete this._strategies[name];
...
use = function (name, strategy) { if (!strategy) { strategy = name; name = strategy.name; } if (!name) { throw new Error('Authentication strategies must have a name'); } this._strategies[name] = strategy; return this; }
...
/**
* Initialize authenticator.
*
* @api protected
*/
Authenticator.prototype.init = function() {
this.framework(require('./framework/connect')());
this.use(new SessionStrategy());
};
/**
* Utilize the given `strategy` with optional `name`, overridding the strategy's
* default name.
*
* Examples:
...
function Strategy() { }
n/a
authenticate = function (req, options) { throw new Error('Strategy#authenticate must be overridden by subclass'); }
...
/**
* Middleware that will authenticate a request using the given `strategy` name,
* with optional `options` and `callback`.
*
* Examples:
*
* passport.authenticate('local', { successRedirect: '/', failureRedirect
: '/login' })(req, res);
*
* passport.authenticate('local', function(err, user) {
* if (!user) { return res.redirect('/login'); }
* res.end('Authenticated!');
* })(req, res);
*
* passport.authenticate('basic', { session: false })(req, res);
...
function authenticate(passport, name, options, callback) { if (typeof options == 'function') { callback = options; options = {}; } options = options || {}; var multi = true; // Cast `name` to an array, allowing authentication to pass through a chain of // strategies. The first strategy to succeed, redirect, or error will halt // the chain. Authentication failures will proceed through each strategy in // series, ultimately failing if all strategies fail. // // This is typically used on API endpoints to allow clients to authenticate // using their preferred choice of Basic, Digest, token-based schemes, etc. // It is not feasible to construct a chain of multiple strategies that involve // redirection (for example both Facebook and Twitter), since the first one to // redirect will halt the chain. if (!Array.isArray(name)) { name = [ name ]; multi = false; } return function authenticate(req, res, next) { if (http.IncomingMessage.prototype.logIn && http.IncomingMessage.prototype.logIn !== IncomingMessageExt.logIn) { require('../framework/connect').__monkeypatchNode(); } // accumulator for failures from each strategy in the chain var failures = []; function allFailed() { if (callback) { if (!multi) { return callback(null, false, failures[0].challenge, failures[0].status); } else { var challenges = failures.map(function(f) { return f.challenge; }); var statuses = failures.map(function(f) { return f.status; }); return callback(null, false, challenges, statuses); } } // Strategies are ordered by priority. For the purpose of flashing a // message, the first failure will be displayed. var failure = failures[0] || {} , challenge = failure.challenge || {} , msg; if (options.failureFlash) { var flash = options.failureFlash; if (typeof flash == 'string') { flash = { type: 'error', message: flash }; } flash.type = flash.type || 'error'; var type = flash.type || challenge.type || 'error'; msg = flash.message || challenge.message || challenge; if (typeof msg == 'string') { req.flash(type, msg); } } if (options.failureMessage) { msg = options.failureMessage; if (typeof msg == 'boolean') { msg = challenge.message || challenge; } if (typeof msg == 'string') { req.session.messages = req.session.messages || []; req.session.messages.push(msg); } } if (options.failureRedirect) { return res.redirect(options.failureRedirect); } // When failure handling is not delegated to the application, the default // is to respond with 401 Unauthorized. Note that the WWW-Authenticate // header will be set according to the strategies in use (see // actions#fail). If multiple strategies failed, each of their challenges // will be included in the response. var rchallenge = [] , rstatus, status; for (var j = 0, len = failures.length; j < len; j++) { failure = failures[j]; challenge = failure.challenge; status = failure.status; rstatus = rstatus || status; if (typeof challenge == 'string') { rchallenge.push(challenge); } } res.statusCode = rstatus || 401; if (res.statusCode == 401 && rchallenge.length) { res.setHeader('WWW-Authenticate', rchallenge); } if (options.failWithError) { return next(new AuthenticationError(http.STATUS_CODES[res.statusCode], rstatus)); } res.end(http.STATUS_CODES[res.statusCode]); } (function attempt(i) { var layer = name[i]; // If no more strategies exist in the chain, authentication has failed. if (!layer) { return allFailed(); } // Get the strategy, which will be used as prot ...
...
/**
* Middleware that will authenticate a request using the given `strategy` name,
* with optional `options` and `callback`.
*
* Examples:
*
* passport.authenticate('local', { successRedirect: '/', failureRedirect
: '/login' })(req, res);
*
* passport.authenticate('local', function(err, user) {
* if (!user) { return res.redirect('/login'); }
* res.end('Authenticated!');
* })(req, res);
*
* passport.authenticate('basic', { session: false })(req, res);
...
function initialize(passport) { return function initialize(req, res, next) { req._passport = {}; req._passport.instance = passport; if (req.session && req.session[passport._key]) { // load data from existing session req._passport.session = req.session[passport._key]; } next(); }; }
...
* Passport to operate.
*
* Options:
* - `userProperty` Property to set on `req` upon login, defaults to _user_
*
* Examples:
*
* app.use(passport.initialize());
*
* app.use(passport.initialize({ userProperty: 'currentUser' }));
*
* @param {Object} options
* @return {Function} middleware
* @api public
*/
...
function SessionStrategy() { Strategy.call(this); this.name = 'session'; }
n/a
function SessionStrategy() { Strategy.call(this); this.name = 'session'; }
n/a
function Strategy() { }
n/a
authenticate = function (req, options) { if (!req._passport) { return this.error(new Error('passport.initialize() middleware not in use')); } options = options || {}; var self = this, su; if (req._passport.session) { su = req._passport.session.user; } if (su || su === 0) { // NOTE: Stream pausing is desirable in the case where later middleware is // listening for events emitted from request. For discussion on the // matter, refer to: https://github.com/jaredhanson/passport/pull/106 var paused = options.pauseStream ? pause(req) : null; req._passport.instance.deserializeUser(su, req, function(err, user) { if (err) { return self.error(err); } if (!user) { delete req._passport.session.user; self.pass(); if (paused) { paused.resume(); } return; } var property = req._passport.instance._userProperty || 'user'; req[property] = user; self.pass(); if (paused) { paused.resume(); } }); } else { self.pass(); } }
...
/**
* Middleware that will authenticate a request using the given `strategy` name,
* with optional `options` and `callback`.
*
* Examples:
*
* passport.authenticate('local', { successRedirect: '/', failureRedirect
: '/login' })(req, res);
*
* passport.authenticate('local', function(err, user) {
* if (!user) { return res.redirect('/login'); }
* res.end('Authenticated!');
* })(req, res);
*
* passport.authenticate('basic', { session: false })(req, res);
...