I've gone through many questions with the same issue, but none of the various solutions have helped. I'm using Redis to store session in a clustered NodeJS+ExpressJS application, but the session is always undefined. Here's my Express setup:
var express = require('express'),
RedisStore = require('connect-redis')(express),
Config = require('./config/config'),
cluster = require("cluster"),
QueryManager = require('./service/query_manager'),
app = express();
// --- Index --- //
function renderSplash(req, res) {
res.render(...);
}
function renderIndex(req, res) {
res.render(...);
}
app.get('/', function(req, res) {
if(req.session.user === null) {
renderSplash(req, res);
} else {
renderIndex(req, res);
}
});
// --- Configuration ---//
//EJS
app.engine('.html', require('ejs').__express);
app.set('view engine', 'html');
app.set('views', __dirname + '/public');
app.configure(function() {
//Session
app.use(express.cookieParser());
app.use(express.session({
store: new RedisStore({
host: Config.redis.host,
port: Config.redis.port
}),
secret: 'Its a secret.',
cookie: { secure: true }
}));
app.use(validateRequest); //Ensures we're at www. to hit the LB
app.use(express.static(__dirname+'/public'));
app.use(express.compress);
app.use(app.router);
});
Even without using the Redis store, I'm getting the following error:
TypeError: Cannot read property 'user' of undefined
You'll have to instantiate the sessions before the routes.
var express = require('express'),
RedisStore = require('connect-redis')(express),
Config = require('./config/config'),
cluster = require("cluster"),
QueryManager = require('./service/query_manager'),
app = express();
app.use(express.cookieParser());
app.use(express.session({
store: new RedisStore({
host: Config.redis.host,
port: Config.redis.port
}),
secret: 'Its a secret.',
cookie: { secure: true }
}));
// --- Index --- //
function renderSplash(req, res) {
res.render(...);
}
function renderIndex(req, res) {
res.render(...);
}
app.get('/', function(req, res) {
if(req.session.user === null) {
renderSplash(req, res);
} else {
renderIndex(req, res);
}
});
Related
I have defined express-myconnection database connection in app.js now i want to use that database connection in models like tasks.js how do I implement that connection in models also.Please suggest me better option.
app.js
var createError = require('http-errors');
var express = require('express');
var session = require('express-session');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var bodyParser = require('body-parser');
// var passport = require('passport');
var cors=require('cors');
var flash = require('connect-flash');
var mysql = require('mysql');
// require('./config/passport')(passport);
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var Tasks=require('./routes/Tasks');
var app = express();
var customers = require('./routes/customers');
var login = require('./routes/login');
var connection = require('express-myconnection');
// view engine setup
// app.set('port', process.env.PORT || 4300);
app.engine('pug', require('pug').__express);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
// app.use(passport.initialize());
app.use(session({
secret: 'justasecret',
resave:true,
cookie: {
httpOnly: true,
maxAge : 10000,
},
saveUninitialized: true
}));
/*------------------------------------------
connection peer, register as middleware
type koneksi : single,pool and request
-------------------------------------------*/
// app.use(
// connection(mysql,{
// host: 'localhost',
// user: 'root',
// password : '',
// port : 3306, //port mysql
// database:'nodejs'
// },'pool')
// );//route index, hello world
dbOptions = {
host: 'localhost',
user: 'root',
password: '',
port: 3307,
database: 'nodejs'
};
// const db = mysql.createPool(dbOptions);
app.use(connection(mysql, dbOptions, 'pool'));
app.use(cors());
app.use(logger('dev'));
// app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(flash());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/customers', customers);
app.use('/admin',login);
app.use('/tasks',Tasks);
// require('./routes/login.js')(app, passport);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// 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;
inside models/tasks.js=>
var Task={
getAllTasks:function(callback){
return db.query("Select * from task",callback);
},
getTaskById:function(id,callback){
return db.query("select * from task where Id=?",[id],callback);
},
addTask:function(Task,callback){
return db.query("Insert into task values(?,?,?)",[Task.Id,Task.Title,Task.Status],callback);
},
deleteTask:function(id,callback){
return db.query("delete from task where Id=?",[id],callback);
},
updateTask:function(id,Task,callback){
return db.query("update task set Title=?,Status=? where Id=?",[Task.Title,Task.Status,id],callback);
}
};
module.exports=Task;
express-myconnection extends request object with getConection(callback) function, this way connection instance can be accessed anywhere in routers during request/response life cycle:
// myroute.js
...
module.exports = function(req, res, next) {
...
req.getConnection(function(err, connection) {
if (err) return next(err);
connection.query('SELECT 1 AS RESULT', [], function(err, results) {
if (err) return next(err);
results[0].RESULT;
// -> 1
res.send(200);
});
});
...
}
...
I have to integrate node.js application with keycloak.The application is in express.But the policies are not enforcing.It grants permission for all the users to access all the api.
For /test api:
Only users with 'chief' role has the access.I have given those policies in keycloak admin console.But those are not reflecting.Why?
User without 'chief' role is also accessing /test
app.js:
'use strict';
const Keycloak = require('keycloak-connect');
const express = require('express');
const session = require('express-session');
const expressHbs = require('express-handlebars');
const app = express();
app.engine('hbs', expressHbs({extname:'hbs',
defaultLayout:'layout.hbs',
relativeTo: __dirname}));
app.set('view engine', 'hbs');
var memoryStore = new session.MemoryStore();
var keycloak = new Keycloak({ store: memoryStore });
app.use(session({
secret:'thisShouldBeLongAndSecret',
resave: false,
saveUninitialized: true,
store: memoryStore
}));
app.use(keycloak.middleware());
app.get('/*', keycloak.protect('user'), function(req, res){
res.send("User has base permission");
});
app.get('/test', keycloak.protect(), function(req, res){
res.send("access granted");
});
app.get('/',function(req,res){
res.send("hello world");
});
app.use( keycloak.middleware( { logout: '/'} ));
app.listen(3000, function () {
console.log('Listening at http://localhost:3000');
});
keycloak.json:
{
"realm": "nodejs-example",
"auth-server-url": "http://localhost:8180/auth",
"ssl-required": "external",
"resource": "nodejs-connect",
"credentials": {
"secret": "451317a2-09a1-48b8-b036-e578051687dd"
},
"use-resource-role-mappings": true,
"confidential-port": 0,
"policy-enforcer": {
"enforcement-mode":"PERMISSIVE",
}
}
You have enforcement-mode in your keycloak.json set to PERMISSIVE, this should be ENCFORCE I believe.
Add the following line in json
"verify-token-audience": true
var Keycloak = require('keycloak-connect');
var hogan = require('hogan-express');
var express = require('express');
var session = require('express-session');
const app = express();
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
app.set('view engine', 'html');
app.set('views', require('path').join(__dirname, '/view'));
app.engine('html', hogan);
var memoryStore = new session.MemoryStore();
var keycloak = new Keycloak({
store: memoryStore });
// session
app.use(session({
secret:'thisShouldBeLongAndSecret',
resave: false,
saveUninitialized: true,
store: memoryStore
}));
app.use(keycloak.middleware({
admin: '/',
protected: '/protected/resourcea'
}));
app.get('/leads/assign',keycloak.enforcer(['leads:assign'],{
claims: function(request){
return {
"location":["chennai"]
}
}
} ), function (req, res) {
res.send("granted");
});
I have an app already built using swig as the templating engine; however, due to recent upgrades I'm having to migrate to nunjucks. I have a page being rendered, but no styles or javascript are being attached. The code worked with swig, but it doesn't appear to be pulling in the content of the stylesheets or JavaScript files.
// setup db
mongoose.connect(secrets.db);
mongoose.connection.on('error', function() {
console.error('MongoDB Connection Error. Make sure MongoDB is running.');
});
var corsOptions = {
origin: '*'
};
// express setup
var app = express();
// This is where all the magic happens!
nunjucks.configure(path.join(__dirname, 'views'), {
autoescape: true,
express: app,
noCache : app.get('env') === 'development',
watch: true
});
app.get('/', function(req, res) {
res.render('index.html');
});
app.locals._ = lodash;
app.locals.stripePubKey = secrets.stripeOptions.stripePubKey;
app.use(favicon(path.join(__dirname + '/../public/favicon.ico')));
app.use(logger('dev'));
app.use(compress);
app.use(bodyParser());
app.use(expressValidator());
app.use(cookieParser());
app.use(express.static(__dirname));
if(app.get('env') !== 'production'){
app.use('/styles', express.static(__dirname + '/../.tmp/styles'));
// app.use('/', routes.styleguide);
}
app.use(session({
resave: true,
saveUninitialized: true,
cookie: {
maxAge: 60 * 1000 // 1 minute
},
secret: secrets.sessionSecret,
store: new MongoStore({
url: secrets.db,
auto_reconnect: true
})
}));
// setup passport authentication
app.use(passport.initialize());
app.use(passport.session());
// other
app.use(flash());
app.use(cors(corsOptions));
var passportMiddleware = require('./middleware/passport');
passportMiddleware(passport);
// setup view helper
app.use(viewHelper);
// setup routes
var routes = require('./routes');
routes(app, passport);
/// catch 404 and forwarding to error handler
app.use(errorHandler.notFound);
/// error handlers
if (app.get('env') === 'development') {
app.use(errorHandler.development);
} else {
app.use(errorHandler.production);
}
module.exports = app;
It's not throwing any errors, just no content being pulled in for styles or JavaScript.
Trying to get sessions set up with Redis. I have my Redis DB in a dokku container, linked to my app (also in a dokku container). I keep getting a session undefined.I've stripped things back to the bare minimum, also checked the order in which things are run. I still get an undefined.
I've read here 'session' is undefined when using express / redis for session store and Express js session undefined to no avail.
I shouldn't need to use cookie-parser, as expression-session has cookie stuff in it, and the docs say cookie-parser can cause problems with expression-session.
var express = require('express');
var session = require('express-session');
var redisStore = require('connect-redis')(session);
var bodyParser = require('body-parser');
var app = express();
app.set('port', (process.env.PORT || 5000));
var redisURL = 'redis://xxxxx:1234567#bar-redis-foo:6379';
var store = new redisStore({ url: redisURL });
app.use(session({
secret: 'ssshhhhh',
store: store,
saveUninitialized: true,
resave: true
}));
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.json()); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
app.get('/', function(req, res, next) {
console.log(req.session); // Logs Undefined
res.send('Hello');
});
Check your redis connection and run again. Sample code is following line.
"use strict";
const express = require("express");
const bodyParser = require("body-parser");
const session = require("express-session");
const RedisStore = require("connect-redis")(session);
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(session({
secret: "$kx(Fj$uB!Ug!#jCkguFmc6f7t<c-e$9",
resave: false,
saveUninitialized: true,
store: new RedisStore({
url: "redis://:********#pub-redis-12766.eu-central-1-1.1.ec2.redislabs.com:12766",
ttl: 5 * 60 // 5 minute (Session store time)
})
}));
app.use(function (request, response, next) {
let path = request.originalUrl;
if (request.session.user) {
request.session.reload(function (err) { //session expire time regenerate
if (!err) {
next();
} else {
response.redirect('/login');
}
});
} else {
if (path == '/login') {
next();
} else {
response.redirect('/login');
}
}
});
app.get('/', function(request, response) {
if (request.session.user) {
response.send(request.session.user);
} else {
response.redirect("/login");
}
});
app.get('/login', function(request, response) {
if (request.session.user) {
response.redirect("/");
} else {
request.session.user = {username: "halil"}; //custom key {user} and custom data {username: "halil"}
}
response.send('Login');
});
app.get('/logout', function(request, response) {
if (request.session.user) {
request.session.destroy();
response.redirect("/login");
} else {
response.redirect("/login");
}
});
app.listen(app.get('port'), function () {
console.log('App is working on port: ' + app.get('port'));
});
I'm just learning testing and I've been at it for a few hours no with no success. Every time I run Mocha, my test shows up in the terminal and returns no result, like this:
Express test app started on port: 3001
addition
It stays blank afterwards. Further, the node processes don't close after testing and when they stack up they crash my computer.
Here is my sample test:
var supertest = require('supertest');
var should = require('should');
process.env.NODE_ENV = 'test';
var app = require('../server');
describe('addition', function() {
//... previous test
it('should return 2 given the url /add/1/1', function(done) {
request(app)
.get('/add/1/1')
.expect(200)
.end(function(err, res) {
should.not.exist(err);
parseFloat(res.text).should.equal(2);
done();
});
});
});
Here is my server.js
// Module Depndencies
var express = require('express'),
fs = require('fs'),
mongoose = require('mongoose'),
passport = require('passport'),
MongoStore = require('connect-mongo')(express),
flash = require('connect-flash'),
env = process.env.NODE_ENV = process.env.NODE_ENV || 'development',
ErrorHandler = require('./app/controllers/api/v1/error_handler_v1'),
config = require('./config/config'),
auth = require('./config/middlewares/authorization');
// Connect The Database
mongoose.connect(config.db);
// Catch Database Connection Error
mongoose.connection.on("error", function(err) {
return console.log("****** Could not connect to mongo server!");
});
// Express Settings
app = express();
app.set('showStackError', true);
//Should be placed before express.static
app.use(express.compress({
filter: function(req, res) {
return (/json|text|javascript|css/).test(res.getHeader('Content-Type'));
},
level: 9
}));
//Setting the fav icon and static folder - tejkh
app.use(express.favicon());
app.use(express.static(config.root + '/public'));
//Don't use logger for test env
if (process.env.NODE_ENV !== 'test') app.use(express.logger('dev'));
//Set views path, template engine and default layout
app.set('views', config.root + '/app/views');
app.set('view engine', 'jade');
// Enable jsonp
app.enable('jsonp callback');
//Bootstrap models
var models_path = __dirname + '/app/models';
var walk = function(path) {
fs.readdirSync(path).forEach(function(file) {
var newPath = path + '/' + file;
var stat = fs.statSync(newPath);
if (stat.isFile()) {
if (/(.*)\.(js|coffee)/.test(file)) {
require(newPath);
}
} else if (stat.isDirectory()) {
walk(newPath);
}
});
};
walk(models_path);
// Bootstrap Passport
require('./config/passport')(passport);
// App.configure
app.configure(function() {
// CookieParser should be above session
app.use(express.cookieParser());
// BodyParser should be above methodOverride
app.use(express.bodyParser());
app.use(express.methodOverride());
// Express/mongo session storage
app.use(express.session({
secret: 'secret',
cookie: {
maxAge: 864000000 // 10 Days in miliseconds
},
store: new MongoStore({
url: config.db,
auto_reconnect: true
})
}));
// Connect flash for flash messages
app.use(flash());
// Use Passport
app.use(passport.initialize());
app.use(passport.session());
// Route
app.use(app.router);
// Error Handler
app.use(function(err, req, res, next) {
if (err.uri) delete err.uri;
if (err.status) {
return res.status(err.status).jsonp(err);
} else {
res.status(500).jsonp({
name: 'InternalError',
message: 'Sorry, something went wrong on our end. We have been notified.',
code: 'server_error',
status: 500
});
}
});
}); // app.configure
//Bootstrap routes
require('./config/routes')(app, passport, auth);
// Start App
app.listen(config.port);
console.log('Express ' + env + ' app started on port: ' + config.port);
// Expose app
exports = module.exports = app;
If you use:
var supertest = require('supertest');
then you should use:
supertest(app)
and not:
request(app)
try this, maybe it will work
request('http://host:port')