I'm trying to use the express session middleware in a separate route handler but the compiler complains that the property 'session' does not exist on type 'Request'.
app.ts
import debug = require('debug');
import express = require('express');
import path = require('path');
import db = require('diskdb');
import bodyParser = require('body-parser');
import session = require('express-session');
import fileStore = require('session-file-store');
import routes from './routes/index/index';
import users from './routes/user';
import register from './routes/users/register';
import login from './routes/users/login';
var app = express();
//Setup sesssion middleware
var sessionFileStore = fileStore(session);
app.use(session({
name: 'server-session-cookie-id',
secret: 'my express secret',
saveUninitialized: true,
resave: true,
store: new sessionFileStore()
}));
//Here we are configuring express to use body-parser as middle-ware.
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/register', session, register);
app.use('/login', session, login);
// 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 handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use((err: any, req, res, next) => {
res.status(err['status'] || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use((err: any, req, res, next) => {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function () {
debug('Express server listening on port ' + server.address().port);
});
login.ts
import express = require('express');
import path = require('path');
import bcrypt = require('bcrypt');
const router = express.Router();
router.get('/', (req: express.Request, res: express.Response) => {
res.render(path.join(__dirname, 'login'), { message: 'display login form', username: '' });
});
router.post('/', (req: express.Request, res: express.Response) => {
var un = req.body.username;
var pw = req.body.password;
var db = require('diskdb');
db = db.connect('db', ['users']);
var existing = db.users.findOne({ username: un });
var all = db.users.find();
bcrypt.compare(pw, existing != null ? existing.password : '', function (err, hashres) {
// res == true
if (hashres) {
res.render(path.join(__dirname, 'login'), {
message: ('handle login form submission for ' + un),
username: un,
result: "the username " + un + " is now logged in.",
resulttype: "success"
});
req.session.user = un;
}
else {
res.render(path.join(__dirname, 'login'), {
message: ('handle login form submission for ' + un),
username: un,
result: "the username and password combination is incorrect.",
resulttype: "error"
});
}
});
});
export default router;
All the examples I've found online say that this is supposed to work, though most don't use a separate file for the route hander...
In your app.ts replace these lines of code
app.use('/register', session, register);
app.use('/login', session, login);
to
app.use('/register', register);
app.use('/login', login);
updated:
try update your code of setup session store by this example
var session = require('express-session');
var FileStore = require('session-file-store')(session);
app.use(session({
store: new FileStore(options),
...
}));
if still not work, express-session has a default session store, use the default session store and check if there still a compiler error.
On a hunch I tried to create the same project without TypeScript and it worked. Once I knew that TS was the culprit it was quite straight forward to find that I had to import an additional node package: #types/express-session
Related
The issue here is when i log in with correct details, the session should be created and cookie should be generated at client side which is happening when i use postman but not in case of web browsers.
I am using the following:
passport for authenticating login details from mongoDB using mongoose
express-session for creating session when a user logs in.
cors at the backend (react is running at port 3000 and node is running at port 4000)
Here is my app.js (backend):
var createError = require('http-errors');
var cookieParser = require('cookie-parser')
var path = require('path');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var serverRouter = require("./routes/server");
var DbRouter = require("./routes/DbRequest");
var ProductRouter = require("./routes/ProductRouter");
var CategoryRouter = require("./routes/CategoryRouter");
const session = require("express-session");
const passport = require("./passport");
var cors = require("cors");
var express = require('express');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser());
// USING SESSION AND PASSPORT
app.use(session({
secret: 'adsdsacoasdqwdn',
resave: false,
saveUninitialized: false,
cookie: { secure: false }
}))
app.use(passport.initialize());
app.use(passport.session());
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use("/api/admin",serverRouter);
app.use("/api/user",DbRouter);
app.use("/api/product",ProductRouter);
app.use("/api/category",CategoryRouter);
app.use(express.json({ extended:false}));
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', "*");
res.header('Access-Control-Allow-Methods','GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
})
// 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;
Here is my file where i am making the routes and creating sessions :
var express = require("express");
var router = express.Router();
var connectDB = require("./connect");
const passport = require("../passport");
connectDB();
router.post("/adminlogin", (req,res,next) => {
passport.authenticate("local-adminSignin",function(err,user,info){
if(err){
return res.status(500).send(err)
}
req.login(user,function(error){
if(error){
return res.status(500).json(err)
}
return res.json(user);
})
})(req,res,next);
})
router.get("/currentAdmin", (req,res,next) => {
res.json(req.user)
})
module.exports = router;
Here , when i make a get request to "/currentAdmin" after i logged in as admin, i should be getting the user object as a response which contains all details of the admin from mongoDB.
POSTMAN LOGIN (i cant post images because this is a new account, i've linked gyazo below) :
https://gyazo.com/5569415297fbe7c7178a93634d1506e6
AFTER LOGIN, MAKING REQUEST TO "/currentAdmin"
https://gyazo.com/cd2ec99e1ee8f959d0c3874b43b76454
But, when i make same request from react, it gives me empty object as a response. One thing i noticed here is cookies are generated in postman and i get response but no cookies are there in the browser after admin login.
MY PASSPORT INDEX.JS FILE
const passport = require("passport");
const User = require("../routes/AdminSchema")
passport.serializeUser(function(user, done) {
console.log('i am serializing the user');
done(null, user.username);
});
passport.deserializeUser(function(username, done) {
console.log('i am de-serializing the user');
User.findOne({username}).lean().exec((err,user) => {
done(err, user);
});
});
//import strategy
const AdminLoginStrategy = require("./AdminLoginStrategy");
passport.use('local-adminSignin',AdminLoginStrategy);
module.exports = passport;
MY LOGIN STRATEGY FILE:
const Strategy = require("passport-local").Strategy;
const User = require("../routes/AdminSchema")
const bcrypt = require("bcryptjs")
const LoginStrategy = new Strategy({passReqToCallback:true},function(req,username,password,done){
User.findOne({username}).lean().exec((err,user) => {
if(err){
return done("db error idk bro",null)
}
if(!user){
return done("user not found!",null)
}
const isPasswordValid = bcrypt.compareSync(password, user.password);
if(!isPasswordValid){
return done("username or password not valid!",null)
}
return done(null,user)
})
})
module.exports = LoginStrategy
PS: If i send text response or other json from "/currentAdmin", I am getting it in react but i am not getting the res.user object which i think is because of cookies not being generated in the browser.
How can i solve this issue? Thanks!
I creating e commerce project . I want to user must have account in order to proceed the checkout process . I am able to create new user with the database but the problem is even the user is login and click buy button ,Still it is showing message user must be login. I want once the user is login then user will be able to buy products..
Here is my app.js code .
'use strict';
var debug = require('debug');
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 { User } = require('./db');
var session = require('express-session');
var passport = require('./passport');
var routes = require('./routes/api/index');
//var users = require('./routes/users');
var app = express();
// 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(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/api', require('./routes/api').route);
//app.use('/', routes);
//app.use('/users', users);
app.use(session({
secret: 'some very very secret thing',
resave: false,
saveUninitialized: true
}));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(passport.initialize());
app.use(passport.session());
app.post('/signup', (req, res) => {
User.create({
username: req.body.username,
password: req.body.password
}).then((user) => {
if (user) {
res.redirect('/signin.html');
}
}).catch((err) => res.send("ERROR CREATING USER"));
});
app.post('/signin', passport.authenticate('local', {
failureRedirect: '/signin.html',
// successRedirect: 'profile'
successRedirect: '/index.html'
}));
// 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 handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function () {
debug('Express server listening on port ' + server.address().port);
});
Here is the user.js code .
var route = require('express').Router();
var { User } = require('../../db');
var session = require('express-session');
var passport = require('../../passport');
route.use(session({
secret: 'some very very secret thing',
resave: false,
saveUninitialized: true
}));
route.use(passport.initialize());
route.use(passport.session());
route.post('/signup', (req, res) => {
User.create({
username: req.body.username,
password: req.body.password
}).then((user) => {
if (user) {
res.redirect('/signin.html');
}
}).catch((err) => res.send("ERROR CREATING USER"));
});
route.post('/signin', passport.authenticate('local', {
failureRedirect: '/signin.html',
// successRedirect: 'profile',
successRedirect: '../../index.html'
}));
route.get('/profile', (req, res) => {
//Available to only logged in people
// Data is different (each user sees own profile)
// console.log(req)
if (req.user) {
res.json(req.user);
} else {
res.send("YOU ARE NOT LOGGED IN");
}
});
exports = module.exports = route;
Here is the screen shot when I run the project for Login page ..
Here is screen shot even user is login still displaying message first you must login.
I am working on a NodeJS app that has the login on a different domain / port.
In my case, I have the login server on localhost:3000 and the application on localhost:3001.
Since I am using PassportJS, when I go to localhost:3001/profile I check if the user is logged in using
function isLoggedIn(req, res, next)
{
if (req.isAuthenticated())
{
return next();
}
res.redirect('http://localhost:3000/login');
}
After login, I send and get an SMS code, I validate the code and then I get redirected back to http://localhost:3001/profile. The problem is, once back, I get redirected to the login server again.
app.post('/login', passport.authenticate('local-login',
{
successRedirect: '/sendsms',
failureRedirect: '/login',
failureFlash: true
}),
function (req, res)
{
if (req.body.remember)
{
req.session.cookie.maxAge = 1000 * 60 * 30;
}
else
{
req.session.cookie.expires = false;
}
});
From /sendsms I get redirected to /validate:
app.post('/validate', function (req, res)
{
console.log("SMS Code: " + req.body.smscode);
if (checkSMSCode(req.body.smscode, req.user))
{
console.log("OK");
res.redirect('http://localhost:3001/profile');
}
else
{
console.log("NOK");
res.redirect('/login');
}
});
This is the app.js on my authentication server:
'use strict';
var debug = require('debug');
var express = require('express');
var session = require('express-session');
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 helmet = require('helmet');
var request = require('request');
var connect = require('connect');
var app = express();
/*
* Connect to the database.
* Pass passport for configuration
*/
require('./config/passportHelper')(passport);
/*
* Setup the express application
*/
app.use(logger('dev'));
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(helmet());
// Setup ejs templating
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// Setup passport sessions
app.use(session(
{
secret: 'mysecretkey',
resave: true,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
/*
* Setup the resources
*/
app.use('/css', express.static(path.join(__dirname, 'public/stylesheets')));
app.use('/js', express.static(path.join(__dirname, 'public/scripts')));
/*
* Setup the routes
*/
require('./routes/index')(app);
require('./routes/login')(app);
require('./routes/signup')(app);
require('./routes/profile')(app);
require('./routes/logout')(app);
require('./routes/redirect')(app);
require('./routes/ticketing')(app);
require('./routes/object')(app);
require('./routes/sendsms')(app);
require('./routes/validate')(app);
/*
* Catch 404 and forward to error handler.
*/
app.use(function (req, res, next)
{
var err = new Error('Not Found');
err.status = 404;
next(err);
});
/*
* Development error handler.
* Will print stacktrace.
*/
if (app.get('env') === 'development')
{
app.use(function (err, req, res, next)
{
res.status(err.status || 500);
console.log("ERROR");
res.render('error',
{
message: err.message,
error: err
});
});
}
/*
* Production error handler.
* No stacktraces leaked to user.
*/
app.use(function (err, req, res, next)
{
res.status(err.status || 500);
res.render('error',
{
message: err.message,
error: {}
});
});
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function ()
{
console.log('Express server listening on port ' + server.address().port);
debug('Express server listening on port ' + server.address().port);
});
I'm pretty sure I'm missing something very obvious, especially since it's the first time I am doing something like this (standalone authentication server) but I can't figure it out and I seem to be running around in circles.
At first, everything was designed as a single application and since /profile was on the same domain, there was no issue.
Any ideas or hints?
I'm trying to get Toastr library to work in my ExpressJS app! I scaffolded the app with the yeoman 'standard' Express Generator...
I've required the lib express-toastr and did the following:
in app.js:
const cookieParser = require('cookie-parser');
const session = require('express-session');
const flash = require('connect-flash');
const toastr = require('express-toastr');
app.use(cookieParser());
app.use(session( {secret: 'xxx', saveUninitialized: true, resave: true} ));
app.use(flash());
app.use(toastr());
in index.js
const express = require('express');
const router = express.Router();
const httpntlm = require('httpntlm');
router.post('/', function (req, res, next) {
// parse inputs
let user = req.body.user || "";
let password = req.body.password || "";
// save in session
req.session.user = {user: user, password: password};
// appropriate response to login attempt
if (!req.session.user) {
res.status(401).send();
}
else {
req.toastr.success('Successfully logged in.', "You're in!");
res.render('groups', {
req: req
});
}
});
module.exports = router;
In index.jade
#{req.toastr.render()}
I'm loading these files in my <head> section:
link(rel='stylesheet', href='//cdnjs.cloudflare.com/ajax/libs/toastr.js/2.0.2/css/toastr.min.css')
script(src='/components/jquery/dist/jquery.min.js')
script(src='//cdnjs.cloudflare.com/ajax/libs/toastr.js/2.0.2/js/toastr.min.js')
Nothing is showing. What am I missing???
-- UPDATE! --
Here is my complete app.js file. I now try to use express-flash and making a dedicated route for showing a flash message. Still not working. Please help!
'use strict';
const express = require('express');
const path = require('path');
const favicon = require('serve-favicon');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const expressSanitizer = require('express-sanitizer');
const login = require('./routes/login');
const apply = require('./routes/apply');
const admin = require('./routes/admin');
var session = require('express-session');
var flash = require('express-flash');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// 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: false}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({
cookie: { maxAge: 60000 },
store: new session.MemoryStore,
saveUninitialized: true,
resave: 'true',
secret: 'secret'
}));
app.use(flash());
// Route that creates a flash message using the express-flash module
app.all('/express-flash', function( req, res ) {
req.flash('success', 'This is a flash message using the express-flash module.');
res.redirect(301, '/');
});
// sanitize inputs
app.use(expressSanitizer());
app.use('/', apply);
app.use('/apply', apply);
app.use('/login', login);
app.use('/admin', admin);
// 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 handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
Try using this middleware in your app.js, I found this here
app.use(function (req, res, next)
{
res.locals.toasts = req.toastr.render()
next()
});
and then access locals in your view as follows:
#{toasts}
This worked for me.
So I am not familiar with your syntax in your index.jade file(!=). What does it do? If you change that line in your index to #{req.toastr.render()} it should work.
So i've been working on getting a user authentication system going and then I encountered a problem where my webpages would no longer load. npm start works fine and the server appears to be running. going to localhost just shows that the bar keeps loading and never eventually loads (before the webpages loaded instantly). I have no idea what I changed but tried to revert as much of the code to the original but still no dice. let me know if any other files are needed. thanks in advance
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 mongoose = require('mongoose');
var passport = require('passport');
var session = require('express-session');
var LocalStrategy = require('passport-local').Strategy;
var flash = require('connect-flash');
// var users = require('./routes/users');
var routes = require('./routes/index');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser('ground glass'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(passport.initialize());
app.use(flash);
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true
}));
app.use('/', routes);
//app.use('/users', users);
// passport config
// var Account = require('./models/accounts');
//passport.use(new LocalStrategy(Account.authenticate()));
//passport.serializeUser(Account.serializeUser());
//passport.deserializeUser(Account.deserializeUser());
// mongoose
//mongoose.connect('mongodb://localhost/test');
// Using the flash middleware provided by connect-flash to store messages in session
// and displaying in templates
//var flash = require('connect-flash');
//app.use(flash());
//require('./routes/index')(app);
/*
passport.use(new LocalStrategy(
function(username, password, done) {
User.findOne({ username: username }, function(err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));*/
// 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 handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res) {
res.render('index', { title: 'test' });
});
module.exports = router;