So I have been working with PassportJS in adding authentication to my site. I am interested in selectively displaying content that reflects whether or not a user is logged in or if he/she is an owner of a document.
I have the following files
app.js (entry point)
//Express set up
let express = require("express");
app = express();
serverPort = 8000;
io = require('socket.io')();
//BodyParser set up
bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: true }));
//Mongoose set up
mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/Woof");
//Models settings
Dog = require("./models/dog");
User = require("./models/user");
//Seed file set up and run!
seed = require("./models/seed");
seed();
//Routes
app.use('/public', express.static(__dirname + '/public'));
app.use(require('./routes/dogOwners'));
app.use(require('./routes/landing'));
app.use(require('./routes/loginAndRegister'));
app.use(require('./routes/map'));
app.use(require('./routes/dog'));
//req.user avalaible to all routes
app.use(function(req,res,next){
res.locals.currentUser = req.user;
next();
});
//App settings
app.set('port', serverPort);
app.set('view engine', 'ejs');
app.set('views', 'views');
app.set('sockets', []);
//Servloger listen:
let server = app.listen(app.get('port'), function() {
console.log('Listening on port ' + app.get('port'));
});
loginAndRegistration.js These are the authentication routes
let express = require('express');
router = express.Router({ mergeParams: true });
User = require("../models/user")
//AUTHENTICATION
let passport = require("passport");
LocalStratergy = require("passport-local");
//PASSPORT CONFIGURATION
app.use(require("express-session")({
secret: "I wanna go poopie",
resave: false,
saveUninitialized: false,
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(function(req,res,next){
res.locals.currentUser = req.user;
next();
});
passport.use(new LocalStratergy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
router.get('/login', function(req,res){
res.render('login');
});
router.post('/login', passport.authenticate('local', {
successRedirect: "/main",
failureRedirect: "/login",
}), function(req, res) {
});
router.get('/logout', function(req,res){
req.logout();
res.redirect("/");
});
router.get('/register', function(req, res) {
res.render('register', {});
});
router.post("/register", function(req, res) {
User.register(new User({ username: req.body.username }), req.body.password, function(error, newlyCreatedUser) {
if (error) {
console.log("COULD NOT REGISTER USER IN THE POST ROUTE");
res.render("register");
console.log(error);
} else {
passport.authenticate("local")(req, res, function() {
let user = req.body.user;
newlyCreatedUser.name = user.name;
newlyCreatedUser.nickname = user.nickname;
newlyCreatedUser.address = user.address;
newlyCreatedUser.email = user.email;
newlyCreatedUser.numberOfDogs = user.numberOfDogs;
newlyCreatedUser.url = "/user/" + newlyCreatedUser.id;
newlyCreatedUser.save(function(error, savedUser) {
console.log("USER REGISTERED");
res.render('maps', {
gmapsCredential: credentials.gmaps,
'authorized': true
});
});
});
}
});
});
function isLoggedIn (req,res,next){
if(req.isAuthenticated()){
return next();
}
res.redirect("/login");
}
module.exports = router;
I wanna be able to call isLoggedIn in all my routes, but I can only use it in the auth routes. How do I selectively export that function alone to all my routes? I also wanna be able to refer to the varaible currentUser in all my .ejs files, however it only works in .ejs files associated with the auth routes. How do I check for currentUser in all my .ejs files?
The crux of your problems are you’ve got too much buried in your loginAndRegistration.js file.
First and foremost, if you want to run isLoggedIn for every route you need to make sure Passport is configured first i.e.
app.use(passport.initialize());
app.use(passport.session());
app.use(function(req,res,next){
res.locals.currentUser = req.user;
next();
});
passport.use(new LocalStratergy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
Needs to be setup before you configure any auth middleware. This will also solve your .ejs problem as user will now be getting serialised for every route and not just the auth ones.
Finally, you can configure your middleware before any routes you want to enforce authentication on
app.use(isLoggedIn);
Related
I want to have an online map which publicly loads and shows all my activities from my Strava account.
I have found a web app on GitHub which does what I want but the user has to log in with the Strava log in screen before he than can see his own activities: https://github.com/nsynes/ActivityMap
It seems it uses Passport Strava to authenticate with Strava: https://www.passportjs.org/packages/passport-strava-oauth2/
Is it possible to adjust the script so it always logs in automatically my account and than shows my activities publicly to everyone who visits the map?
The full script is here: https://github.com/nsynes/ActivityMap/blob/master/activity-map-app.js
My STRAVA_CLIENT_ID and STRAVA_CLIENT_SECRET are from my Strava account and saved in a .env file.
const express = require('express')
const passport = require('passport')
const util = require('util')
const StravaStrategy = require('passport-strava-oauth2').Strategy
const dotenv = require('dotenv');
const path = require('path');
const cookieParser = require('cookie-parser')
const bodyParser = require('body-parser');
const session = require('express-session');
var strava = require('strava-v3');
const decode = require('geojson-polyline').decode
const geodist = require('geodist');
dotenv.config();
const port = process.env.PORT || 3000
const app = express();
// configure Express
//app.use(express.logger());
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: false }));
//app.use(express.methodOverride());
app.use(session({
secret: 'monkey tennis',
resave: true,
saveUninitialized: true,
maxAge: 1800 * 1000
}));
app.use(passport.initialize());
app.use(passport.session());
app.use('/css', express.static(path.join(__dirname, 'css')));
app.use('/fontawesome', express.static(path.join(__dirname, 'fontawesome')));
app.use('/js', express.static(path.join(__dirname, 'js')));
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
// Passport session setup.
passport.serializeUser(function(user, done) { done(null, user) });
passport.deserializeUser(function(obj, done) {done(null, obj) });
passport.use(new StravaStrategy({
clientID: process.env.STRAVA_CLIENT_ID,
clientSecret: process.env.STRAVA_CLIENT_SECRET,
callbackURL: "/auth/strava/callback"
},
function(accessToken, refreshToken, profile, done) {
// asynchronous verification, for effect...
process.nextTick(function () {
// To keep the example simple, the user's Strava profile is returned to
// represent the logged-in user. In a typical application, you would want
// to associate the Strava account with a user record in your database,
// and return that user instead.
return done(null, profile);
});
}
));
app.get('/', ensureAuthenticated, function(req, res){
pagePath = path.join(__dirname, '/index.html');
res.sendFile(pagePath);
});
app.get('/userPhoto', ensureAuthenticated, function(req, res){
if ( req.user ) {
res.json({ 'photo': req.user.photos[req.user.photos.length-1].value });
} else {
res.sendStatus(404);
}
});
// Use passport.authenticate() as route middleware to authenticate the
// request. Redirect user to strava, then strava will redirect user back to
// this application at /auth/strava/callback
app.get('/auth/strava',
passport.authenticate('strava', { scope: ['activity:read'], approval_prompt: ['force'] }),
function(req, res){
// The request will be redirected to Strava for authentication, so this
// function will not be called.
});
// GET /auth/strava/callback
// Use passport.authenticate() as route middleware to authenticate the
// request. If authentication fails, the user will be redirected back to the
// login page. Otherwise, the primary route function function will be called,
// which, in this example, will redirect the user to the home page.
app.get('/auth/strava/callback',
passport.authenticate('strava', { failureRedirect: '/login' }),
function(req, res) {
res.redirect('/');
});
app.get('/logout', function(req, res){
req.logout();
res.cookie("connect.sid", "", { expires: new Date() });
res.render('login', { user: req.user });
});
app.get('/login', function(req, res){
res.render('login', { user: req.user });
});
I've spent more time than I'd like to admit scouring countless posts online that have the same problem as me, to no avail. The majority of solutions seemed to be things like not including
passReqToCallback: true in my LocalStrategy.
passport.serializeUser() and passport.deserializeUser() in my init file.
app.use(passport.initialize()) and app.use(passport.session()) in app.js.
Requiring and using app.use(cookieParser()) in app.js.
Passing cookie parser my secret key.
Adding proxy and cookie attributes to my expressSession variable in app.js.
Invoking req.login inside passport.authenticate within my page route.
And several other little tweaks I can't remember...
My login.js is as follows;
var LocalStrategy = require('passport-local').Strategy;
var User = require('../../models/user');
var bCrypt = require('bcrypt-nodejs');
module.exports = function(passport) {
passport.use('login', new LocalStrategy({passReqToCallback: true},
function(req, username, password, done) {
//Queries MongoDB For User
User.findOne({'username': username}, function(err, user) {
//In The Event Of An Error, Throw It
if (err) {
return done(err);
}
//Username Does Not Exist, Log Error, Callback, Flash Error Message
if (!user){
console.log('User: '+ username + ", does not exist.");
return done(null, false, req.flash('message', 'User Not found.'));
}
//User Exists, But Password Is Incorrect
if (!isValidPassword(user, password)){
console.log('Invalid Password');
return done(null, false, req.flash('message', 'Invalid Password')); // redirect back to login page
}
//If No Previous Error Conditions Are Met - Username/Password Are Correct
console.log("Validated User: " + username + ".");
//req.user = user;
return done(null, user);
}); //End of User.findOne()
}) //End of new LocalStrategy
); //End of passport.use()
/*
var isValidPassword = function(user, password){
return bCrypt.compareSync(password, user.password);
}
*/
//Passwords are not currently hashed in my DB, so ignore bcrypt for now.
var isValidPassword = function(user, password) {
return user.password == password;
}
}
My passport-init.js file
var login = require('./login');
var User = require('../../models/user');
module.exports = function(passport){
//Serialise User
passport.serializeUser(function(user, done) {
console.log("Serializing User: " + user.username + "\n" + user + ".");
done(null, user._id);
});
//De-Serialise User
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
console.log("Deserializing User: " + user.username + "\n" + user);
done(err, user);
});
});
//Setting up Passport Strategy for Login
login(passport);
}
My index.js file contains the POST Login route
/* POST Login Page*/
router.post('/login', passport.authenticate('login', {
successRedirect: '/dashboard',
failureRedirect: '/login',
failureFlash: true
}));
And dashboard.js contains all the routing for /dashboard/other-pages.
These ones are protected by the isAuthenticated function.
var express = require('express');
var router = express.Router();
var database = require('../public/javascripts/db-connect.js');
var isAuthenticated = function(req, res, next) {
console.log("User: " + req.user);
console.log("Authenticated?: " + req.isAuthenticated());
if (req.isAuthenticated()) {
return next();
} else {
res.redirect('/unauthorised');
}
}
module.exports = function(passport) {
//Routes /dashboard --> dashboard.pug
router.get('/', isAuthenticated, function(req, res, next) {
database.getData("busdata", function(err, data) {
if (err) {
console.error(err);
} else {
res.render('dashboard', {title: 'Dashboard', busdata: data});
}
});
});
//Routes /dashboard/journeys --> journeys.pug
router.get('/journeys', isAuthenticated, function(req, res, next) {
database.getData("journeydata", function(err, data) {
if (err) {
console.error(err);
} else {
res.render('journeys', {title: 'Journey Graphs', journeydata: data});
}
});
});
return router;
}
So when I run the app;
I check localhost:3000/dashboard and localhost:3000/dashboard/journeys. They correctly re-direct me to /unauthorised.
Navigate to /login.
Enter a correct username and password, the console then spits out:
Validated User: TomPlum. Meaning passport.use() reached return done(null, user)
Serialising User: TomPlum + the objects properties
POST /login 302 time ms
User: undefined from isAuthenticated
isAuthenticated? false
GET /dashboard 302 time ms
Deserialising User: TomPlum + the objects properties
I'm then redirected to /unauthorised as isAuthenticated() evaluates to false.
Why is req.user undefined? Should I be using a LocalStrategy if my MongoDB is not-local? (Amazon Atlas Server). Other forum posts have suggested it could be a cookie issue but I've included the relevant cookie-parser includes in my app.js file.
app.js is here in-case it's an order issue.
//Require Variables
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');
//Mongo DB Connection Settings
var dbConfig = require('./db'); //db.js contains DB URL
var mongoose = require('mongoose');
mongoose.connect(dbConfig.url); //dbConfig.url refers to the export in db.js
//Page Routing
//var index = require('./routes');
var users = require('./routes/users');
var dashboard = require('./routes/dashboard')(passport);
var app = express();
app.d3 = require('d3');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public/images', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser('urban_sensing'));
app.use(express.static(path.join(__dirname, 'public')));
//app.use('/', index);
app.use('/dashboard', dashboard);
app.use('/users', users);
//Configuring Passport
var passport = require('passport');
var expressSession = require('express-session');
app.enable('trust-proxy');
app.use(expressSession({
secret: 'urban_sensing',
resave: true,
saveUninitialized: true,
proxy: true,
cookie: {
secure: true,
maxAge: 3600000
}
}));
app.use(passport.initialize());
app.use(passport.session());
//Flash Messaging For Passport
var flash = require('connect-flash');
app.use(flash());
//Initialize Passport
var initPassport = require('./public/javascripts/passport-init');
initPassport(passport);
var index = require('./routes/index')(passport);
app.use('/', index);
//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;
Some of the app.use(expressSession({..})); properties may currently be unnecessary as they've been added in an attempt to fix the issue.
Any help would be appreciated.
After too much time on this, turns out it was simply the order of app.js.
By moving
var dashboard = require('./routes/dashboard')(passport);
app.use('/dashboard', dashboard);
below all the passport configuration. It now works correctly. It seems that something wasn't initialised correctly during the routing of /dashboard when it was before the passport code.
Updated app.js
//Require Variables
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');
//Mongo DB Connection Settings
var dbConfig = require('./db'); //db.js contains DB URL
var mongoose = require('mongoose');
mongoose.connect(dbConfig.url); //dbConfig.url refers to the export in db.js
//Page Routing
//var index = require('./routes');
var users = require('./routes/users');
var app = express();
app.d3 = require('d3');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public/images', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser('urban_sensing'));
app.use(express.static(path.join(__dirname, 'public')));
//app.use('/', index);
app.use('/users', users);
//Configuring Passport
var passport = require('passport');
var expressSession = require('express-session');
app.use(expressSession({
secret: 'urban_sensing',
resave: false,
saveUninitialized: true,
cookie: {
maxAge: 3600000 //1 Hour
}
}));
app.use(passport.initialize());
app.use(passport.session());
//Flash Messaging For Passport
var flash = require('connect-flash');
app.use(flash());
//Initialize Passport
var initPassport = require('./public/javascripts/passport-init');
initPassport(passport);
var dashboard = require('./routes/dashboard')(passport);
app.use('/dashboard', dashboard);
var index = require('./routes/index')(passport);
app.use('/', index);
//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;
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;
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);
});
}));
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.
I'm currently working on a project where a User logs in with Facebook, sees a map with their location pinpointed, and then can see their friends who have also logged in on the map (with the distance).
The next step is to store this data in a database.
As I'm fairly new to using MongoDB, I would like some guidance on how to approach taking the Facebook login/Geolocation data and inserting it into the database. I'm comfortable with inputting BSON objects into the database manually from the command line, but I cannot seem to find the best way of doing this in my code.
The code is below - it would really help to have some guidance on first steps to getting the post data and putting it into the MongoDB database. Thank you!
var express = require('express')
var passport = require('passport')
var util = require('util')
var FacebookStrategy = require('passport-facebook').Strategy
var logger = require('morgan')
var session = require('express-session')
var sessionStore = require('sessionstore');
var bodyParser = require("body-parser")
var cookieParser = require("cookie-parser")
var methodOverride = require('method-override');
var port = process.env.PORT || 3000
var io = require('socket.io')(http);
var http = require('http').Server(app);
var markers = [];
var server = require('http').createServer(app);
var passportStrategy = require('../utils/passport-strategy');
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var FACEBOOK_APP_ID = "*";
var FACEBOOK_APP_SECRET = "*";
passport.use(passportStrategy.facebook);
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(obj, done) {
done(null, obj);
});
var sessionData = session({
store: sessionStore.createSessionStore(),
secret: "your_secret",
cookie: { maxAge: 2628000000 },
resave: true,
saveUninitialized: true
});
passport.use(new FacebookStrategy({
clientID: FACEBOOK_APP_ID,
clientSecret: FACEBOOK_APP_SECRET,
callbackURL: "http://localhost:3000/auth/facebook/callback"
},
function(accessToken, refreshToken, profile, done) {
process.nextTick(function () {
return done(null, profile);
});
}
));
var app = express();
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(sessionData);
app.use(logger("combined"));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(methodOverride());
app.use(session({
secret: "keyboard cat",
saveUninitialized: true, // (default: true)
resave: true, // (default: true)
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res){
res.render('index', { user: req.user });
});
app.get('/account', ensureAuthenticated, function(req, res){
res.render('account', { user: req.user });
});
app.get('/login', function(req, res){
res.render('login', { user: req.user });
});
app.get('/auth/facebook',
passport.authenticate('facebook'),
function(req, res){
});
app.get('/auth/facebook/callback',
passport.authenticate('facebook', { failureRedirect: '/login' }),
function(req, res) {
res.redirect('/');
});
app.get('/logout', function(req, res){
req.logout();
res.redirect('/');
});
app.get('/mapjs', function(req, res){
res.sendFile(__dirname + '/public/map.js');
});
// Socket markers start
io.on('connection', function(socket) {
console.log('a user connected');
socket.on('marker', function(data) {
data.socketId = socket.id;
markers[socket.id] = data;
console.log('marker latitude: ' + data.lat + ', marker longitude:' + data.lng);
socket.broadcast.emit('show-marker', data);
});
// socket.on('show-marker', )
socket.on('show-user-location', function(data) {
socket.broadcast.emit('show-user-location', data);
});
});
app.listen(port, function(){
console.log('five minute catch up is on port 3000');
});
// socket markers end
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/login')
}
module.exports = server;
can you strip this down so that you are doing only the insertion of some static data before connecting it up to facebook and having sockets in there. Every extra bit of code will get in the way of knowing whether what change you try is actually doing what you want.
Regarding the best way to insert data programmatically in mongodb, I believe this is the relevant part of the documentation:
http://docs.mongodb.org/manual/core/write-operations-introduction/
db.users.insert(
{
name: "sue",
age: 26,
status: "A"
}
)
Short summary of the problem: I'm using a new version of express (4.9.0) on a Node.js website which has a few public pages and a few private pages, which I'm putting behind a Google OAuth2 login, using PassportJS. When I request a page behind the sign-in, the user keeps being asked to sign-in; req.isAuthenticated() isn't "sticky". I've seen some comments online that there are can be problems with cookie parser versions being incompatible, so that could be the issue here.
Here is my (rather long) app.js:
var express = require('express');
var http = require('http');
var path = require('path');
var passport = require('passport');
var googleStrategy = require('passport-google-oauth').OAuth2Strategy;
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var app = express();
app.use(cookieParser());
app.use(bodyParser());
app.use(session({ secret: 'mysecret' }));
app.set('view engine', 'html');
app.set('views', path.join(__dirname, 'views'));
app.engine('html', require('ejs').renderFile);
app.set('port', process.env.PORT || 3000);
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(obj, done) {
done(null, obj);
});
passport.use(new googleStrategy({
clientID: clientId,
clientSecret: secret,
callbackURL: "http://127.0.0.1:3000/auth/google/callback"
},
function (accessToken, refreshToken, profile, done) {
process.nextTick(function () {
return done(null, profile);
});
}
));
app.get('/auth/google',
passport.authenticate('google', { scope: ['https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/userinfo.email'] }),
function(req, res){
});
app.get('/auth/google/callback',
passport.authenticate('google', { failureRedirect: '/login' }),
function(req, res) {
console.log("successfully authenticated with google");
res.redirect('/');
});
app.get('/login', function(req, res){
res.redirect('/auth/google');
});
app.get('/privatepage', ensureAuthenticated, function(req, res) {
var dostuff = module.listThings(function(rows) {
res.render('somepage.html', {
title : "some page",
data : rows
});
});
});
function ensureAuthenticated(req, res, next) {
console.log("in ensureAuth", req.isAuthenticated());
console.log("session data", req.session);
console.log("user data", req.user);
if (req.isAuthenticated()) { return next(); }
res.redirect('/login');
}
var server = app.listen(3000, function() {
var host = server.address().address
var port = server.address().port
console.log('App listening at http://%s:%s', host, port)
})
After the first login, if I visit the /privatepage URL, I get re-directed through Google and land on the homepage again. This is what's in the log from those console.log lines:
in ensureAuth false
session data { cookie:
{ path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true },
passport: {} }
user data undefined
I assume this is some session issue where it doesn't store the user's logged in state, but I'm a node newbie & am a little stuck on how to fix this. I'm running on a single computer, so it's not a multiple machines issue. Any debugging suggestions, or ideas on the conflict causing the logged-in state not to be stored?