I am doing a react project using express and passport-local for the authentication part based on this tutorial : https://scotch.io/tutorials/easy-node-authentication-setup-and-local
The authentification work very well, I added the express router to define my routes for my api, but when I call for example "/api/myroute" the router of express creates an other session and I lose the user, so my function isLoggedIn
blocks the call of my controllers because there is no user in this new session. So my question is : Why the router recreate a session ? What it is wrong in my configuration ? Here is my code :
//server.js
var path = require('path');
var webpack = require('webpack');
var webpackDevMiddleware = require('webpack-dev-middleware');
var webpackHotMiddleware = require('webpack-hot-middleware');
var config = require('./webpack.config');
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var configDB = require('./config/database.js');
var router = express.Router();
// configuration ===============================================================
mongoose.connect(configDB.url); // connect to our database
require('./config/passport')(passport); // pass passport for configuration
// set up our express application
app.use(morgan('dev')); // log every request to the console
app.use(cookieParser()); // read cookies (needed for auth)
app.use(bodyParser()); // get information from html forms
app.set('view engine', 'ejs'); // set up ejs for templating
// required for passport
app.use(session({ secret: 'secret' })); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session
var compiler = webpack(config);
app.use(webpackDevMiddleware(compiler, { noInfo: true, publicPath: config.output.publicPath }));
app.use(webpackHotMiddleware(compiler));
app.use('/plugins/bootstrap', express.static(path.join(__dirname, './plugins/bootstrap')));
app.use('/plugins/jquery', express.static(path.join(__dirname, './plugins/jquery')));
app.use('/plugins/font-awesome', express.static(path.join(__dirname, './plugins/font-awesome')));
// all of our routes will be prefixed with /api
app.use('/api', router);
// routes ======================================================================
require('./api/routes.js')(app, passport,router); // load our routes and pass in our app and fully configured passport
// launch ======================================================================
app.listen(port, function(error) {
if (error) {
console.error(error)
} else {
console.info("==> 🌎 Listening on port %s. Open up http://localhost:%s/ in your browser.", port, port)
}
});
console.log('The magic happens on port ' + port);
And here is my routes.js :
module.exports = function(app, passport,router) {
var MyController = require("../api/controllers/mycontroller");
// =====================================
// HOME PAGE (with login links) ========
// =====================================
app.get('/', function(req, res) {
console.log("welcome")
res.render('index.ejs', { message: ""}); // load the index.ejs file
});
// =====================================
// LOGIN ===============================
// =====================================
// show the login form
app.get('/login', function(req, res) {
console.log("login")
// render the page and pass in any flash data if it exists
res.render('index.ejs', { message: req.flash('loginMessage') });
});
app.post('/login', passport.authenticate('local-login', {
successRedirect : '/welcome', // redirect to the secure profile section
failureRedirect : '/login', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
}));
// =====================================
// SIGNUP ==============================
// =====================================
// show the signup form
app.get('/signup', function(req, res) {
console.log("signup")
// render the page and pass in any flash data if it exists
res.render('signup.ejs', { message: req.flash('signupMessage') });
});
// process the signup form
app.post('/signup', passport.authenticate('local-signup', {
successRedirect : '/welcome', // redirect to the secure profile section
failureRedirect : '/signup', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
}));
// process the signup form
// app.post('/signup', do all our passport stuff here);
// =====================================
// LOGOUT ==============================
// =====================================
app.get('/logout', function(req, res) {
console.log("logout")
req.logout();
res.redirect('/');
});
router.get('/myroute', isLoggedIn, function(req, res) {
//HERE the router recreate a session and req.user is now undefined why ?
MyController.getAllObjects(req,res);
});
// =====================================
// HOME SECTION =====================
// =====================================
// we will want this protected so you have to be logged in to visit
// we will use route middleware to verify this (the isLoggedIn function)
app.get('*', isLoggedIn, function(req, res) {
console.log("HOME")
res.render('home.ejs', {
user : req.user // get the user out of session and pass to template
});
});
};
// route middleware to make sure a user is logged in
function isLoggedIn(req, res, next) {
// if user is authenticated in the session, carry on
if (req.isAuthenticated())
return next();
console.log("redirect because not log in")
// if they aren't redirect them to the home page
res.redirect('/');
}
The function for login, logout, signin... are a copy paste of the tutorial.
You seem to be using the fetch library. This library does not include the domain cookies by default, so in order to work your request should look like this:
fetch('/api/myroute', {
credentials: 'same-origin' // This is the line you are missing
}).then(response => response.json())
.then(json => {
dispatch({
type: types.MY_ACTION, forms: json, receivedAt: Date.now()
})
})
See this link for more information.