Skip to content

Instantly share code, notes, and snippets.

@theangryangel
Created February 28, 2013 21:54
Show Gist options
  • Star 54 You must be signed in to star a gist
  • Fork 17 You must be signed in to fork a gist
  • Save theangryangel/5060446 to your computer and use it in GitHub Desktop.
Save theangryangel/5060446 to your computer and use it in GitHub Desktop.
sails (v0.8.82) + passport + passport-local Rough Example. For the love of all that is holy, don't use this in production.
// config/application.js
var passport = require('passport')
, LocalStrategy = require('passport-local').Strategy;
// some static users
var users = [
{ id: 1, username: 'bob', password: 'secret', email: 'bob@example.com' }
, { id: 2, username: 'joe', password: 'birthday', email: 'joe@example.com' }
];
// helper functions
function findById(id, fn) {
var idx = id - 1;
if (users[idx]) {
fn(null, users[idx]);
} else {
fn(new Error('User ' + id + ' does not exist'));
}
}
function findByUsername(username, fn) {
for (var i = 0, len = users.length; i < len; i++) {
var user = users[i];
if (user.username === username) {
return fn(null, user);
}
}
return fn(null, null);
}
// Passport session setup.
// To support persistent login sessions, Passport needs to be able to
// serialize users into and deserialize users out of the session. Typically,
// this will be as simple as storing the user ID when serializing, and finding
// the user by ID when deserializing.
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
findById(id, function (err, user) {
done(err, user);
});
});
// Use the LocalStrategy within Passport.
// Strategies in passport require a `verify` function, which accept
// credentials (in this case, a username and password), and invoke a callback
// with a user object. In the real world, this would query a database;
// however, in this example we are using a baked-in set of users.
passport.use(new LocalStrategy(
function(username, password, done) {
// asynchronous verification, for effect...
process.nextTick(function () {
// Find the user by username. If there is no user with the given
// username, or the password is not correct, set the user to `false` to
// indicate failure and set a flash message. Otherwise, return the
// authenticated `user`.
findByUsername(username, function(err, user) {
if (err) { return done(err); }
if (!user) { return done(null, false, { message: 'Unknown user ' + username }); }
if (user.password != password) { return done(null, false, { message: 'Invalid password' }); }
return done(null, user);
})
});
}
));
// export
module.exports = {
// Name of the application (used as default <title>)
appName: "Sails Application",
// Port this Sails application will live on
port: 1337,
// The environment the app is deployed in
// (`development` or `production`)
//
// In `production` mode, all css and js are bundled up and minified
// And your views and templates are cached in-memory. Gzip is also used.
// The downside? Harder to debug, and the server takes longer to start.
environment: 'development',
// Custom express middleware - we use this to register the passport middleware
express: {
customMiddleware: function(app)
{
app.use(passport.initialize());
app.use(passport.session());
}
}
};
// api/controllers/AuthController.js
var passport = require('passport');
var AuthController = {
login: function (req,res)
{
res.view();
},
process: function(req, res)
{
passport.authenticate('local', function(err, user, info)
{
if ((err) || (!user))
{
res.redirect('/login');
return;
}
req.logIn(user, function(err)
{
if (err)
{
res.view();
return;
}
res.redirect('/');
return;
});
})(req, res);
},
logout: function (req,res)
{
req.logout();
res.redirect('/');
}
};
module.exports = AuthController;
// api/policies/authenticated.js
// We use passport to determine if we're authenticated
module.exports = function(req, res, next)
{
if (req.isAuthenticated())
return next();
res.redirect('/login')
}
// views/auth/login.ejs
<form action="/login" method="post">
<div>
<label>Username:</label>
<input type="text" name="username"/><br/>
</div>
<div>
<label>Password:</label>
<input type="password" name="password"/>
</div>
<div>
<input type="submit" value="Submit"/>
</div>
</form>
<p><small>Hint - bob:secret</small></p>
// config/policies.js
/**
* Policy defines middleware that is run before each controller/controller.
* Any policy dropped into the /middleware directory is made globally available through sails.middleware
* Below, use the string name of the middleware
*/
module.exports.policies = {
// default require authentication
// see api/policies/authenticated.js
'*': 'authenticated',
// whitelist the auth controller
'auth':
{
'*': true
}
};
@vicapow
Copy link

vicapow commented Mar 16, 2013

thanks for this!

@webjames
Copy link

Thanks for this, i have created a working example application here: https://github.com/webjames/sails-passport-example

@denovohealth
Copy link

Could the user be accessed via the model rather than having it in application.js ?

@RunnerRick
Copy link

Great, Gist.

However, you're missing the route configuration for the /login URL. GET /login needs to show the form and POST /login needs to process it.

I made a fork of your Gist and added the code to config/routes.js if you want to copy it into yours.

See https://gist.github.com/RunnerRick/6001897

// Custom routes for login:
'get /login': {
    controller: 'auth',
    action: 'login'
},

'post /login': {
    controller: 'auth',
    action: 'process'
}

@bhanuc
Copy link

bhanuc commented Jul 18, 2013

Hi,
Can you suggest some changes which I should before I use this in production . Also how can I hash my passwords

@mugli
Copy link

mugli commented Jul 21, 2013

authenticated policy (authenticated.js) crashes for websocket requests. Possible workaround:
http://stackoverflow.com/questions/17365444/sails-js-passport-js-authentication-through-websockets

@adityamukho
Copy link

Another example, adapted for Sails.js 0.9.x. This example uses basic authentication, but other strategies can be easily plugged in:

https://gist.github.com/adityamukho/6260759

@xdissent
Copy link

@Mantish
Copy link

Mantish commented Aug 28, 2013

Thanks a lot!
I've forked it and made it compatible with sails 0.9: https://gist.github.com/Mantish/6366642

@anhnt
Copy link

anhnt commented Jan 7, 2014

Thanks a lot,
I've folked and made some changes to authenticate with database (mysql) as well as compatible with Sails 0.98
https://gist.github.com/anhnt/8297229

@AnalogJ
Copy link

AnalogJ commented Feb 20, 2014

I've put together a quick tutorial for getting everything working with Sails 0.99. Creating a Sails Application using Passport Authentication

@jessecogollo
Copy link

With sails 0.9.x do not work !!! help me please !!!

@JetFault
Copy link

@nlt2390
Copy link

nlt2390 commented Apr 29, 2014

I suggest we should not use:
express: {
customMiddleware: function(app)
{
app.use(passport.initialize());
app.use(passport.session());
}
}
Setup passport like that makes the function "passport.deserializeUser" run many times( passport deserialize run on every requests: all css, js , images files... ), we can initialize passport in policies instead:

var passport = require('passport');

module.exports.policies = {
'*': [ passport.initialize(), passport.session() ]
}

balderdashy/sails#1224

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment