Aleph
Aleph

Reputation: 76

Passport authentication not work for one specific route with express router

I'm trying to access 'testpage' route. But the req.isAuthenticated() returns false only for this route. (This route was there before I started to add authentication). I'm able to go to login page and authenticate with google. Then I can access 'signup' or 'user_profile' route without problems.

After login if I try:

localhost:8080/testpage

the server sends me to "/". But if I try:

localhost:8080/testpage#

with hash sign in the end, the page is rendered.

// routes/users.js

var express = require('express');
var router = express.Router();

module.exports = function (passport) {
  router.get('/login', function (req, res) {
    res.render('login', { message: req.flash('loginMessage') });
  });

  router.get('/auth/google', passport.authenticate('google', { scope: ['profile', 'email'] }));

  router.get('/auth/google/callback',
    passport.authenticate('google', {
      successRedirect: '/',
      failureRedirect: '/'
    }));

  router.get('/user_profile', isLoggedIn, function (req, res) {
    res.render('user_profile');
  });

  router.get('/signup', isLoggedIn, function (req, res) {
    res.render('signup');
  });

  router.get('/testpage', isLoggedIn, function (req, res) {
    res.render('testpage');
  });

  return router;

};

function isLoggedIn(req, res, next) {
  if (req.isAuthenticated())
    return next();

  res.redirect('/');
}

Any ideas why this is happening?


* update *

Here my app.js

var express       = require('express');
var path          = require('path');
var favicon       = require('serve-favicon');
var logger        = require('morgan');
var cookieParser  = require('cookie-parser');
var bodyParser    = require('body-parser');
var passport      = require('passport');
var flash         = require('connect-flash');
var session       = require('express-session');
var db            = require('./mongoose');

var app = express();

require('./config/passport')(passport);

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use(session({
    secret: 'secret123', 
    resave: true,
    saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());


var users = require('./routes/users')(passport);

app.use('/', users);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});


module.exports = app;

Upvotes: 0

Views: 2174

Answers (2)

Ahmed Hassan
Ahmed Hassan

Reputation: 577

It could be due to the express-session middleware that is needed for passport. you can fix it by using middleware in following order.

var session = require('express-session')
var app = express()
app.set('trust proxy', 1) // trust first proxy
app.use(session({
   secret: 'yoursecret',
   resave: true,
   saveUninitialized: true,
   cookie: { secure: true },
   // you can store your sessions in mongo or in mysql or redis where ever     you want.
   store: new MongoStore({
      url: "mongourl",
      collection: 'sessions' // collection in mongo where sessions are to be saved
   })
}))
// Init passport 
app.use(passport.initialize());
// persistent login sessions 
app.use(passport.session());

See https://github.com/expressjs/session for more details.

Also I think so you have not config google strategy. try some thing like following

var GoogleStrategy = require('passport-google-oauth').OAuthStrategy;

// Use the GoogleStrategy within Passport.
//   Strategies in passport require a `verify` function, which accept
//   credentials (in this case, a token, tokenSecret, and Google profile), and
//   invoke a callback with a user object.

passport.use(new GoogleStrategy({
    consumerKey: GOOGLE_CONSUMER_KEY,
    consumerSecret: GOOGLE_CONSUMER_SECRET,
    callbackURL: "http://www.example.com/auth/google/callback"
  },
  function(token, tokenSecret, profile, done) {
      User.findOrCreate({ googleId: profile.id }, function (err, user) {
      return done(err, user);
  });
}));

Upvotes: 3

Aleph
Aleph

Reputation: 76

Finally after one entire day I just realized that when I was typing localhost:8000/testpage in the url bar it was been changed to www.localhost:8000/testpage. And the auth dos not work with www*. Another thing is that google chrome tries to predict what url you will type and this could cause this type of error, and it is annoying at debugging. So I unchecked this options at chrome's settings, preventing prediction.

unchecked google chrome's settings

Upvotes: 0

Related Questions