I try to configure my connect-mongo in the way I can use session in nodejs that is persisted with mongo. I use following code
var mongoose = require('mongoose');
function connect(url, callback) {
mongoose.connect(url);
var connection = mongoose.connection;
connection.on('error', console.error.bind(console, 'connection error:'));
connection.once('open', function() {
console.log("Mongoose connected at: ", url);
callback(connection);
});
}
var express = require("express");
var body_parser = require('body-parser');
var cookie_parser = require('cookie-parser');
var hogan_express = require('hogan-express');
var session = require('express-session');
var mongo_store = require('connect-mongo')(session);
var express = require("express");
var app = express();
app.engine('html', hogan_express);
app.set('view engine', 'html');
app.set("views", "views");
app.use("/libs", express.static("bower_components"));
if (!config.development) {
app.use(express.static("min"));
}
app.use(express.static("public"));
connect("MONGODBURL",function(mongoose_connection){
app.use(body_parser.json());
app.use(cookie_parser());
app.use(session({
secret: "asd",
store: new mongo_store({
mongoose_connection: mongoose_connection
// db: mongoose_connection.db
})
}));
})
I have tried everything but executing some code I have never the object session in my res refrence.
Getting: TypeError: Cannot set property 'asd' of undefined
Code:
app.get("/rest/test",function(req, res) {
req.session.asd="test";
res.send(req.session.asd)
});
Somone could give a hint for a solution?
You need to define your routes after your configure your session.
...
app.use(session....
...
app.get("/...
Inside your connect's callback in your case. Probably start listening inside it only as well.
connect("MONGODBURL",function(mongoose_connection){
app.use(body_parser.json());
app.use(cookie_parser());
app.use(session({
secret: "asd",
store: new mongo_store({
mongoose_connection: mongoose_connection
// db: mongoose_connection.db
})
}));
app.get("/rest/test",function(req, res) {
req.session.asd="test";
res.send(req.session.asd)
});
app.listen(...
});
Related
I'm using the Wes Boss Node.js tutorial and have been encountering a number of issues with schema errors.
My database is currently running on mLab and MongoDB Compass. It was fine yesterday when I left for work, and I had just added my first bit of data to the DB successfully. This morning I go to continue where I left off, and everything is suddenly broken.
I've tried deleting the node_modules directory, running npm cache clean, and npm install. I have tried changing the order of the dependencies. I thought it might be that the connection just needed restarted, so I closed the connection, exited Compass, re-opened and re-connected to the DB. I tried deleting the "sessions" table and re-connecting. No such luck.
I've tried plugging the database's server address into my browser's URL bar and I receive a message indicating that the connection was successful.
Error:
MissingSchemaError: Schema hasn't been registered for model "Store". Use mongoose.model(name, schema)
at MissingSchemaError (C:\Users\Misha\Desktop\dang-thats-delicious\node_modules\mongoose\lib\error\missingSchema.js:20:11)
app.js:
const express = require('express');
const session = require('express-session');
const mongoose = require('mongoose');
const MongoStore = require('connect-mongo')(session);
const path = require('path');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const passport = require('passport');
const promisify = require('es6-promisify');
const flash = require('connect-flash');
const expressValidator = require('express-validator');
const routes = require('./routes/index');
const helpers = require('./helpers');
const errorHandlers = require('./handlers/errorHandlers');
const app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(expressValidator());
app.use(cookieParser());
app.use(session({
secret: process.env.SECRET,
key: process.env.KEY,
resave: false,
saveUninitialized: false,
store: new MongoStore({ mongooseConnection: mongoose.connection })
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use((req, res, next) => {
res.locals.h = helpers;
res.locals.flashes = req.flash();
res.locals.user = req.user || null;
res.locals.currentPath = req.path;
next();
});
app.use((req, res, next) => {
req.login = promisify(req.login, req);
next();
});
app.use('/', routes);
app.use(errorHandlers.notFound);
app.use(errorHandlers.flashValidationErrors);
if (app.get('env') === 'development') {
app.use(errorHandlers.developmentErrors);
}
app.use(errorHandlers.productionErrors);
module.exports = app;
index.js:
const express = require('express');
const router = express.Router();
const storeController = require('../controllers/storeController');
const { catchErrors } = require('../handlers/errorHandlers');
router.get('/', storeController.homePage);
router.get('/add', storeController.addStore);
router.post('/add', catchErrors(storeController.createStore));
module.exports = router;
start.js:
require('./models/Store');
const mongoose = require('mongoose');
const Store = mongoose.model('Store');
require('dotenv').config({ path: 'variables.env' });
mongoose.connect(process.env.DATABASE);
mongoose.Promise = global.Promise;
mongoose.connection.on('error', (err) => {
console.error(`${err.message}`);
});
require('./models/Store');
const app = require('./app');
app.set('port', process.env.PORT || 7777);
const server = app.listen(app.get('port'), () => {
console.log(`Express running → PORT ${server.address().port}`);
});
Well, I think I solved my own problem. My storeController.js file needed require('../models/Store'); at the top, right below const mongoose = require('mongoose');
However, now I'm getting another error, and I believe it's related to removing my stored sessions from the DB:
express-session deprecated req.secret; provide secret option at app.js:38:9
Going to attempt to re-create the DB and see what happens.
I want to use
req.user.id
inside
io.sockets.on('connection', module.exports = function(socket){}
so I tried to using this line
socket.request.client.user
like that on my
io.socket
io.sockets.on('connection', module.exports = function(socket,client,req){
connections.push(socket);
app.use(session({ secret: 'keyboard cat',resave: true, saveUninitialized:true})); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
console.log('connected: %s socket connected -session',socket.request.client.user ,connections.length);
but i get undefined on console
that's are my full code full code
var authController = require('./app/controllers/authcontroller.js');
var auth = require('./app/routes/auth.js');
var express = require('express')
var app = express()
var passport = require('passport')
var session = require('express-session')
var bodyParser = require('body-parser')
var env = require('dotenv').load()
var exphbs = require('express-handlebars')
app.use(session({secret: 'ssshhhhh'}));
app.use(passport.initialize())
app.use(passport.session())
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
var mysql = require('mysql');
var connection = mysql.createConnection({
host: 'localhost',
database: 'db_users',
user: 'root',
password: '',
});
users = [];
connections = [];
app.use('/cssFiles', express.static('/opt/lampp/htdocs/x/regtest/using-passport-with-sequelize-and-mysql-master/app/routes/assets'));
//For BodyParser
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
// For Passport
app.use(session({ secret: 'keyboard cat',resave: true, saveUninitialized:true})); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
//passport.authenticate('local-signin');
//For Handlebars
app.set('views', './app/views')
app.engine('hbs', exphbs({extname: '.hbs'}));
app.set('view engine', '.hbs');
app.get('/', function(req, res){
console.log('idddddd',req.sessionID);
res.send('Welcome to Passport with Sequelize');
});
//Models
var models = require("./app/models");
//Routes
var authRoute = require('./app/routes/auth.js')(app,passport);
//load passport strategies
require('./app/config/passport/passport.js')(passport,models.user);
//Sync Database
models.sequelize.sync().then(function(){
console.log('Nice! Database looks fine')
}).catch(function(err){
console.log(err,"Something went wrong with the Database Update!")
});
server.listen(process.env.PORT || 5000, function(err){
if(!err)
console.log("Site is live"); else console.log(err)
});
console.log('Server running...');
app.get('/', function(req, res){
res.sendFile('/opt/lampp/htdocs/x/regtest/using-passport-with-sequelize-and-mysql-master/app/routes/page.html');
});
//connection.connect();
io.sockets.on('connection', module.exports = function(socket,client,req){
//con
connections.push(socket);
//app.use(session);
app.use(session({ secret: 'keyboard cat',resave: true, saveUninitialized:true})); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
console.log('connected: %s socket connected session',socket.request.client.user ,connections.length);
req.user is only available in express middleware unfortunately. You'll have to use something like https://www.npmjs.com/package/passport.socketio if you want to access passports user info.
You will have to use some sort of persistent store as well such as redis or mongodb
I am trying to reuse the database object.The session intialization is working fine outside the Mongoconnect callback. But when I move it inside the call back , the session cookie is not being set in the browser . Any ideas??
var express=require('express');
var bodyParser=require('body-parser');
var cookieParser=require('cookie-parser');
var session=require('express-session');
var mongodb=require('mongodb'),
MongoClient = mongodb.MongoClient;
var MongoStore = require('connect-mongo')(session);
var util=require('util');
var assert=require('assert');
var db;
var app=express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
app.use(cookieParser());
MongoClient.connect('mongodb://localhost:27017/mydb',function(err,database){
if(!err)
{
app.use(session(
{ name:'sessionCookie',secret:'secret',saveUninitialized:true,resave:true ,
store: new MongoStore({ db:database })
}
));
app.listen(3000);
}
});
This seems to be a timing issue between the time the app object is intialized aand the session is intilaized. I chnaged the code a bit and the issue seems to be fixed. I am not entirely sure about the root cause. Feel free to chip in
var express=require('express');
var bodyParser=require('body-parser');
var cookieParser=require('cookie-parser');
var session=require('express-session');
var mongodb=require('mongodb'),
MongoClient = mongodb.MongoClient;
var MongoStore = require('connect-mongo')(session);
var util=require('util');
var assert=require('assert');
var db;
var app;
MongoClient.connect('mongodb://localhost:27017/mydb',function(err,database){
if(!err)
{
app=express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
app.use(cookieParser());
app.use(session(
{ name:'sessionCookie',secret:'secret',saveUninitialized:true,resave:true ,
store: new MongoStore({ db:database })
}
));
app.listen(3000);
}
});
I'm in a node.js app, and I'm trying to get the session data to store in a mongoDB database.
But the I dont understand the usage of connect-mongo and I would like if someone could explain to me the correct usage and what I can't connect to my mongoDB db.
my app.js code is
var config = require('./config')
, express = require('express')
, passport = require('passport')
, site = require('./site')
, oauth2 = require('./oauth2')
, user = require('./user')
, client = require('./client')
, token = require('./token')
, https = require('https')
, fs = require('fs')
, path = require('path')
, mongoose = require('mongoose')
, MongoStore = require('connect-mongo')(express);
var sessionStorage;
var MongoStore = require('connect-mongo')(express);
console.log('Using MongoDB for the Session');
sessionStorage = new MongoStore({
db: config.session.dbName
});
var app = express();
app.set('view engine', 'ejs');
app.use(express.logger());
app.use(express.cookieParser());
app.use(express.urlencoded());
app.use(express.json());
//Session Configuration
app.use(express.session({
secret: config.session.secret,
store: sessionStorage,
key: "authorization.sid",
cookie: {maxAge: config.session.maxAge }
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(function(err, req, res, next) {
if(err) {
res.status(err.status);
res.json(err);
} else {
next();
}
});
require('./auth')(passport);
app.get('/', site.index);
app.get('/login', site.loginForm);
app.post('/login', site.login);
app.get('/logout', site.logout);
app.get('/account', site.account);
app.get('/dialog/authorize', oauth2.authorization);
app.post('/dialog/authorize/decision', oauth2.decision);
app.post('/oauth/token', oauth2.token);
app.get('/api/userinfo', user.info);
app.get('/api/clientinfo', client.info);
app.get('/api/tokeninfo', token.info);
app.use(express.static(path.join(__dirname, 'public')));
mongoose.connect('mongodb://user:pass#host:10026/dbName');
var db = mongoose.connection;
db.on('error',console.error.bind(console, 'connection error:'));
db.once('open', function callback() {
console.log("Connected to db");
});
mongoose.set('debug', true);
var options = {
key: fs.readFileSync('certs/privatekey.pem'),
cert: fs.readFileSync('certs/certificate.pem')
};
https.createServer(options, app).listen(3000);
console.log("Authorization Server started on port 3000");
and output error is
authorization-server\node_modules\connect-mongo\lib\connect-mongo.js:155
throw new Error('Error connecting to database <' + err + '>');
^
Error: Error connecting to database <Error: failed to connect to [127.0.0.1:27017]>
Notice in your error message mongoose is trying to connect to the localhost at the default port. Also you need to define your db connection at the top of your file.
Change:
mongoose.connect('mongodb://user:pass#host:10026/dbName');
To:
mongoose.connect('mongodb://localhost/dbName');
Initially this error message started appearing very infrequently, but started to appear more regularly and now appears 4/5 times I run my application.
I'm handling my session store with Mongo and as I understand it, the TTL index is used to make the session data expire.
/home/dan/dev/audio-wave/node_modules/connect-mongo/lib/connect-mongo.js:161
throw new Error('Error setting TTL index on collection : ' + s
^
Error: Error setting TTL index on collection : sessions
at /home/dan/dev/audio-wave/node_modules/connect-mongo/lib/connect-mongo.js:161:23
at /home/dan/dev/audio-wave/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/db.js:1404:28
at /home/dan/dev/audio-wave/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/db.js:1542:30
at /home/dan/dev/audio-wave/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/cursor.js:159:22
at commandHandler (/home/dan/dev/audio-wave/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/cursor.js:678:48)
at Db._executeQueryCommand (/home/dan/dev/audio-wave/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/db.js:1802:12)
at Cursor.nextObject (/home/dan/dev/audio-wave/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/cursor.js:729:13)
at Cursor.toArray (/home/dan/dev/audio-wave/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/cursor.js:158:10)
at Cursor.toArray (/home/dan/dev/audio-wave/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/scope.js:10:20)
at /home/dan/dev/audio-wave/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/db.js:1541:65
Here's the code that ties it together
var sessionStore = new MongoStore({ db: 'audio-drop' })
, cookieParser = express.cookieParser('waytoblue')
, SessionSockets = require('session.socket.io')
, sockets = new SessionSockets(io, sessionStore, cookieParser);
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.logger('dev'));
app.use(cookieParser);
app.use(express.session({
store: sessionStore
}));
According to db.version() from the Mongo shell, I'm running 2.4.9 and I'm using version 0.4.0 of connect-mongo.
There seem to be a number of people who've hit this issue, but it seems that most of them resolved to being credential issues, my local mongo is not secured with authentication, so this can't be the problem. Any ideas?
As I said in your comment, essentially Express is receiving connections before the session store is fully connected. The solution is to wait for the connection to occur before allowing your application to start listening.
You can avoid this problem by using a callback on MongoStore creation, or passing in an already active connection.
Example using connect-mongo's Callback
var sessionStore = new MongoStore({ url: 'someConnectionUrl', db: 'audio-drop' }, function(e) {
var cookieParser = express.cookieParser('waytoblue');
app.use(cookieParser);
app.use(express.session({
store: sessionStore
}));
app.listen();
});
Simple Mongoose Example
var mongoose = require('mongoose');
mongoose.connect('localhost', function(e) {
// If error connecting
if(e) throw e;
var sessionStore = new MongoStore({ mongoose_connection: mongoose.connection }),
cookieParser = express.cookieParser('waytoblue');
app.use(cookieParser);
app.use(express.session({
store: sessionStore
}));
app.listen();
});
Upgrade to connect-mongo version 0.8.0 which worked for me.
angular fullstack example
It´s just to encapsulate all the other stuff inside the mongoose.connect callback function
See my server/app.js
/**
* Main application file
*/
'use strict';
// Set default node environment to development
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
var express = require('express');
var mongoose = require('mongoose');
var config = require('./config/environment');
// Connect to database
mongoose.connect(config.mongo.uri, config.mongo.options , function(e){
// Populate DB with sample data
if(config.seedDB) { require('./config/seed'); }
// Setup server
var app = express();
var server = require('http').createServer(app);
var socketio = require('socket.io')(server, {
serveClient: (config.env === 'production') ? false : true,
path: '/socket.io-client'
});
require('./config/socketio')(socketio);
require('./config/express')(app);
require('./routes')(app);
// Start server
server.listen(config.port, config.ip, function () {
console.log('Express server listening on %d, in %s mode', config.port, app.get('env'));
});
// Expose app
exports = module.exports = app;
});
Hope it helps!!