0
votes

So I am trying to build a simple login/authorization tool utilizing node.js, passport.js and angular2. My current issue is that while a user can login, the session information doesn't appear to be passed to the front end server or the front end server doesn't pass the passport information back.

When logging in the user appears to get all the way to the portion where the res.send is called, and at that point serialize has been called and req.sessions.passport.user has been set; however, when the user tries to go to an authorized page, while the cookie is there, the passport is missing. While Deserialized is also never called, the middleware is called/appears called. When the middleware gets to the deserializer there is no passport/user attached thus deserialize is never called.

At this point I am wondering if it might be a CORS issue or something with angular2, but I have been working on this for several days and appear to be doing it the suggested way. I have also tried rebuilding it and setting up CORS in multiple ways along with the middleware and I am running out of ideas. I am also using express session but that appears to be working because the cookie I create in that exists.

Session Data at the end of auth but before responding to the site Session { cookie: { path: '/', _expires: null, originalMaxAge: null, httpOnly: true, secure: false }, passport: { user: anonymous { username: 'test', hash: '4024ca40c4372e029459a1d2d52a25b2fc4642f980f6cc948cc4b35f6350adde', } } }

Session Data after making further requests Session { cookie: { path: '/', _expires: null, originalMaxAge: null, httpOnly: true, secure: false } }

Relevant Code: Passport.js

passport.serializeUser((user, done) => {
  done(null, user);
});

passport.deserializeUser((users, done) => {
  var id=users.username;
  db.one('select * from users where username = $1', id)
  .then((user) => {
    done(null, user);
  })
  .catch((err) => { done(err,null); });

});

local.js

const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const init = require('./passport');
var promise = require('bluebird'); 
var options = {
 // Initialization Options
 promiseLib: promise
};

var hashclient = require('hashapi-lib-node');
const crypto = require('crypto');
var hash = crypto.createHash('sha256');
var pgp = require('pg-promise')(options);
var connectionString = 'postgresql://...';
var db = pgp(connectionString);
const optionsPassport = {};
init();

passport.use(new LocalStrategy(optionsPassport, (username, password, done) => {
 db.one('select * from users where username = $1', username)
 .then((user) => {
   hash.update(password);
   var encryptedPassword=hash.digest('hex');
   hash = crypto.createHash('sha256');
  if (!user) return done(null, false, { message: 'Incorrect username.' });
  if (encryptedPassword!=user.password) {
   return done(null, false, { message: 'Incorrect information.' });
  } else { 
     return done(null, user);
    }
 })
.catch((err) => { return done(err); });
}));

helpers.js

function loginRequired(req, res, next) {
  if (!req.user) return res.status(401).json({status: 'Please log in'});
  return next();
}

Router.js example

const users = require('express').Router();
const auth = require('./auth');
const update = require('./update');
const password = require('./password');
const authHelpers = require('./helpers');
const passport = require('./local');

users.post('/update',  authHelpers.loginRequired, update);
users.get('/:userId',  authHelpers.loginRequired, single);
users.post('/create',   create);
users.post('/auth', passport.authenticate('local'), auth);

app.js

var passport = require('passport');
app.use(cookieParser())
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({
  secret: 'X+a1+TKXwd26mkiUUwqzqQ==',
  resave:true,
  saveUninitialized:true,
  cookie:{secure:false}
}));
app.use(passport.initialize());
app.use(passport.session());


app.use(function (req, res, next) {
    var allowedOrigins = ['http://localhost:3000']
    res.header('Access-Control-Allow-Origin', allowedOrigins);
    res.header( 'Access-Control-Allow-Headers', 'withCredentials, Access-Control-Allow-Headers, Origin, X-Requested-With, X-AUTHENTICATION, X-IP, Content-Type, Accept, Access-Control-Request-Method, Access-Control-Request-Headers');
    res.header( 'Access-Control-Allow-Methods', 'GET, OPTIONS, HEAD, POST, PUT, DELETE');
    res.header( 'Access-Control-Allow-Credentials', true);

    next();
  });

var routes = require('./routes');
app.use('/', routes);

front end http service

getData (url:string, data:any): Observable<any>  {
 var headers = new Headers({ 'Content-Type': 'application/json', withCredentials: true  });
 var options = new RequestOptions({ headers: headers });
 return this.http.get(url,options)
                 .map((res: Response): data => res.json())
                 .catch(this.handleError);
}
1
promiseLib: promise is in the wrong category.Roman C
I doubled check but according to github.com/vitaly-t/pg-promise#initialization-options it appears to be the right category for postgres?Lucas Hendren
Does it have integrity constraints enforced that rule? Post all of them.Roman C
Let me know if I am answering your questions wrong, and Ill post this up top. But there are no specific restraints to the postgres database. Its a basic table that mainly consits of a handful of VARCHARs, two booleans and one Date object. And session should be using memory store?Lucas Hendren
Session is very bad, you might have memory leaks and that stolen session somewhere, and never use VARCHAR, only VARCHAR2 or NVARCHAR.Roman C

1 Answers

0
votes

The issue was on the front end I was not setting withCredentials to true in the correct location

    var options = new RequestOptions({ headers: headers, withCredentials: true   });