title: SSO Authentication for Node.js REST API (cansecurity, passport)
body: <p>I have been working to build a simple REST API to a database through Node.js, and am hoping to implement a basic single-sign-on structure with authorization rules for different users.  I started off using <a href="http://passportjs.org/" rel="nofollow">passport</a> (specifically passport-local), which does a good job of authenticating and making easy login/logout services -- but seems to not be friendly with a stateless setup.</p>
  
  <p>In researching further, I came across <a href="https://github.com/deitch/cansecurity" rel="nofollow">cansecurity</a> and think it has the functionality I'm looking for.  After reading through the documentation, there are a few things I am having trouble with in really getting into this:</p>
  
  <p><strong>1) How do I actually send a login/logout request?</strong></p>
  
  <p>I see how cansecurity allows for authorization for different routes, and I wrote a validation function to check hashed passwords, retrieve the user, etc. But does anyone have any insight into actually performing the single-sign-on to get a user logged in?</p>
  
  <p><strong>2) Is there an easy way to integrate the access information into an external source?</strong>  </p>
  
  <p>Ideally, I'd like to have a mobile app using the API to perform database operations (hence the desire to have SSO and a fairly robust authorization framework).</p>
  
  <p>If anyone has used either passport or cansecurity for a similar setup, how did you do it and what steps may I be missing?</p>
  
  <p><strong>SETTING UP CANSECURITY:</strong></p>
  
  <pre><code>var cs = require('cansecurity')
      , cansec = cs.init( 
      {
          sessionExpiry: 60, 
          sessionKey: SESSIONKEY,
          validate: 
              function(username, password, done) {
                  User.findOne({ username: username }, function(err, user) {
                      if (err) return done(err);
                      if (!user) {
                          return done(false, null, { message: 'Incorrect username.' }, null);
                      }
                      if(password !== undefined){
                          user.validPassword(password, function(err, result) {
                              if (result == true) return done(true, user, null, user.password);
                              else return done(false, null, {message: 'Incorrect password.'}, null);
                          });
                      }
                      else return done(true, user, null, user.password);
                  });
          }
      })
  </code></pre>
  
  <p><strong>SETTING UP PASSPORT</strong></p>
  
  <pre><code>//passport
  passport.use(new LocalStrategy(
     function(username, password, done) {
        User.findOne({ username: username }, function(err, user) {
           if (err) return done(err);
           if (!user) {
               return done(null, false, { message: 'Incorrect username.' });
           }
           user.validPassword(password, function(err, result) {
               if (result == true) return done(null, user);
               else return done(null, false, {message: 'Incorrect password.'});
           });
      });
  }));
  
  passport.serializeUser(function(user, done) {
     done(null, user.id);
  });
  
  passport.deserializeUser(function(id, done) {
     User.get(id, function(err, user) {
         done(err, user);
     });
  });
  
  // Routes
  //login
  app.post('/login',
        passport.authenticate('local', { successRedirect: '/home',
                                         failureRedirect: '/',
                                         failureFlash: false })
  );
  
  //logout
  app.get('/logout', function(req, res){
     req.logout();
     res.redirect('/');
  });
  </code></pre>