I'm new to express and i'm trying to save some data in session and then retrieve it in another query. My client app is an AngularJS app.
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 cookieSession = require('cookie-session');
app.use(cookieParser());
app.use(cookieSession({
name: 'session',
keys: ['mySecret']
}));
app.use(bodyParser.json());
When retrieving session, it's always an empty object
{}
What can be the cause ?
Thank you !
EDIT
This my app.js now
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 cookieSession = require('cookie-session');
var methodOverride = require('method-override');
var session = require('express-session');
//Services
var routes = require('./routes/index');
var users = require('./routes/users');
var typesOperateurs = require('./routes/typesOperateurs');
var domains = require('./routes/domains');
var categories = require('./routes/categories');
var donnees = require('./routes/donnees');
var arcepData = require('./routes/arcepData');
var generalData = require('./routes/generalData');
var app = express();
var properties = require('./configs/properties');
// 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: true }));
//app.use(cookieParser('arcepSecret'));
/*app.use(cookieSession({
name: 'session',
keys: ['arcepSecret'],
httpOnly : false
}));*/
app.use(session({
secret:'arcepSecret',
resave: true,
saveUninitialized: true,
name : 'arcep.sid'
}));
app.use(bodyParser.json());
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', properties.clientHost);
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
//app.use(methodOverride);
//app.use(express.static(path.join(__dirname, 'public')));
//storing models
app.use(function(req, res, next) {
req.models = app.models;
next();
});
// Routes
app.use('/arcep', routes);
app.use('/arcep/users', users);
app.use('/arcep/typesOperateurs', typesOperateurs);
app.use('/arcep/domains', domains);
app.use('/arcep/categories', categories);
app.use('/arcep/donnees', donnees);
app.use('/arcep/arcep_data', arcepData);
app.use('/arcep/general_data', generalData);
// 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;
I'm populating the session inside
router.post('/link1', function (req, res, next) {
req.session.name = 'khalil';
});
And i'm trying to retrieve it inside
router.post('/link2', function (req, res, next) {
console.log(req.session);
})
EDIT2
I found that if invoke the services from the browser directly, everything goes fine, but when trying that from the client app wich is an angular app hosted on a tomcat server, the problem occures.
The solution is to allow credentials in the angular app.
.config(function ($routeProvider, $httpProvider) {
$httpProvider.defaults.withCredentials = true;
$http doesn't send cookie in Requests
I suggest you import the express-session (https://github.com/expressjs/session).
Try this:
var expressSession = require('express-session');
app.use(expressSession({secret:'somesecrettokenhere'}));
After to set and get the values in session:
app.get('/', function(req, res) {
req.session.hello_message = "Hello world";
res.send(req.session.hello_message);
});
The session variable hello_message will be available at everywhere in the application.
Follow full example.
1) Create file called confi.json in the same level of the app.js:
{
"SECRET": "Test",
"KEY": "test.sid",
"MAX_AGE": {
"maxAge": 3600000
}
}
2) Alter the app.js for this:
var express = require('express')
, cfg = require('./config.json')
, load = require('express-load')
, bodyParser = require('body-parser')
, compression = require('compression')
, methodOverride = require('method-override')
, expressSession = require('express-session')
, cookieParser = require('cookie-parser')
, app = express()
, cookie = cookieParser(cfg.SECRET);
app.use(compression());
app.use(cookie);
app.use(expressSession({
secret: cfg.SECRET,
name: cfg.KEY,
resave: false,
saveUninitialized: false,
}));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(methodOverride('_method'));
app.get('/', function(req, res) {
req.session.hello_message = "Hello world";
console.log(req.session.hello_message);
});
app.listen(5000, function(){
console.log("Test running");
});
module.exports = app;
3) Update the package.js:
{
"name": "test",
"version": "0.0.1",
"description": "test",
"private": true,
"scripts": {
"start": "node app.js"
},
"dependencies": {
"body-parser": "~1.12.0",
"cookie-parser": "~1.3.4",
"debug": "~2.1.1",
"ejs": "~2.3.1",
"express": "~4.12.2",
"express-load": "1.1.8",
"morgan": "~1.5.1",
"serve-favicon": "~2.2.0"
}
}
4) Run npm update --save for save the dependencies.
5) Open the browser: localhost:5000 and the message should appear in the console.
As noted in the answer to a related SO question, this can occur if you're using fetch to get data from your server but you don't pass in the credentials option:
fetch('/link2', {
method: 'POST',
credentials: 'same-origin' // <- this is mandatory to deal with cookies
})
Cookies won't be passed to the server unless you include this option.
Related
I have developed web app using angularjs single page application.Now I am building my own web server using nodejs.
The index page is visible when page is loaded but on navigation to other pages.
The get request goes on infinite loop with 304 status.
**Please note I need css and javascript for bootstrap and jquery.**When these are loaded I receive the error.I have inserted app.js(server config),index.js(nodejs routing config),moduleapp.js(angularjs routing config) and picture of error.
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider
.when("/home", {
templateUrl : "/views/home.hbs",
controller : "homeCtrl"
})
.when("/aboutme",{
templateUrl:"/views/aboutme.hbs",
controller:"aboutCtrl"
})
.when("/education", {
templateUrl : "/views/education.hbs",
controller : "eduCtrl"
})
.when("/interest",{
templateUrl:"/views/interest.hbs",
controller:"interestCtrl"
})
.when("/gallery",{
templateUrl:"/views/gallery.hbs",
controller:"galleryCtrl"
})
.when("/contact", {
templateUrl : "/views/contact.hbs",
controller : "contactCtrl"
});
});
app.controller("homeCtrl", function ($scope) {
$scope.msg = "Welcome to homepage";
});
app.controller("aboutCtrl", function ($scope) {
$scope.msg = "About me";
});
app.controller("eduCtrl", function ($scope) {
$scope.msg = "Hi Academics";
});
app.controller("interestCtrl", function ($scope) {
$scope.msg = "My interests";
});
app.controller("galleryCtrl",function($scope){
$scope.msg="My photos";
})
app.controller("contactCtrl", function ($scope) {
$scope.msg = "Contact me";
});
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('layout');
});
router.get('/:name', function(req, res, next) {
var name=req.params.name;
res.render(name);
});
module.exports = router;
<!-- end snippet -->
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 hbs=require('express-handlebars');
var index = require('./routes/index');
var app = express();
// view engine setup
app.engine('hbs',hbs({extname:'hbs'}))
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: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
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;
this is my code I am running the server but I can't get the page index.html
the error is
app.get('/',function(request,response){
console.log("/");
response.sendFile(__dirname+"/views/index.html");
})
The error is
This 127.0.0.1 page can’t be found
No webpage was found for the web address: http://127.0.0.1:5000/home
HTTP ERROR 404
I dont think the server is getting the get request. I don't see the console.log() getting called.
The entire code:
var http = require("http");
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 routes = require('./routes/index');
var users = require('./routes/users');
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(express.static(__dirname+"/"));
app.use('/', routes);
app.use('/users', 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 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
});
});
}
app.get('/',function(request,response){
console.log("/");
res.sendfile('views/index.html', {root: __dirname });
});
// 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: {}
});
});
// http.createServer(function (request, response) {
// // Send the HTTP header
// // HTTP Status: 200 : OK
// // Content Type: text/plain
// response.end('Hello World\n');
// response.writeHead(200, {'Content-Type': 'text/plain'});
// // Send the response body as "Hello World"
// }).listen(8081);
app.listen(5000);
// Console will print the message
console.log('Server running at http://127.0.0.1:5000/');
module.exports =app;
In your error, http://127.0.0.1:5000/home is not found that mean you did not define /home route. So you need to update app.get('/') route as following
app.get('/home?',function(request,response){
console.log("Url: " + request.url);
response.sendfile('views/index.html', {root: __dirname });
});
Try this
app.use('/', routes);
app.use('/users', users);
//add your route to get file
app.get('/',function(request,response){
console.log("/");
response.sendfile('views/index.html', {root: __dirname });
});
See the doc understand it correctly res.sendFile
Hit this URL http://127.0.0.1:5000/ to get your file in browser
I am new in MEAN technology and Developing Web APP. I established the
Connection and login successfully. I want to establish the session after login
But I don't know how to established the session in MEAN app.
Connection established using 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 routes = require('./routes/index');
var api = require('./routes/api');
var users = require('./routes/users');
// database connectivity
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/ditroapp');
var db = mongoose.connection;
db.on('error', function (err) {
console.log('mongo connection error', err);
});
db.once('open', function () {
console.log('mongo connected.');
});
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// 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('/', routes);
app.use('/api', api);
app.use('/users', 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 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;
and here is code in controller.js using this I login successful.
$scope.loginpage = function(){
$http({
method: 'POST',
url: '/api/login',
data: {email:$scope.email, password:$scope.password}
}).then(function successCallback(response) {
if(response.data.error)
{
alert("Invalid email pasword");
}
else
{
$scope.dp = response.data;
$localStorage.pp = $scope.dp;
//console.log($localStorage.pp)
$location.path('/addseat');
}
}, function errorCallback(response) {
alert("Invalid email pasword");
});
}
I'm inexperienced in backend and working with Node and trying to set up an $http POST request to send a form to Express. Each time I make the request, my callback data is null. Perhaps my Express routes are not configured correctly? I'm using Angular to communicate with Express/Node to send an email through nodemailer (which I've already properly configured).
Here is my $http POST request:
client/service/emailer/emailer.js
angular.module('public').factory('EmailerService',function($http) {
return {
postEmail: function(emailData, callback) {
console.log('call http with object', emailData);
$http({
method: 'POST',
url: 'http://my-website.com/server/routes/emailer',
data: emailData,
headers: { "Content-Type": "application/json" },
responseType: 'json'
}).success(function(data, status, headers, config) {
console.log('success', data, status);
}).error(function(data, status, headers, config) {
console.log('error', data, status);
}).catch(function(error){
console.log('catch', error);
});
}
};
});
Here is my server side Express configuration:
server/routes/emailer.js
var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');
var logger = require('morgan');
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(logger('dev'));
app.post('/emailer', function(req,res) {
// NOTHING LOGS HERE
console.log(res, req, req.body, res.body);
});
module.exports = app;
Nothing logs to the console here, and the error handling on the $http request returns this:
emailer.js:4 call http with Object {email: "asdf"}
angular.js:8632 OPTIONS http://matt-mcdaniel.com/server/routes/emailer net::ERR_CONNECTION_TIMED_OUT(anonymous function) # angular.js:8632sendReq # angular.js:8426$get.serverRequest # angular.js:8146deferred.promise.then.wrappedCallback # angular.js:11682deferred.promise.then.wrappedCallback # angular.js:11682(anonymous function) # angular.js:11768$get.Scope.$eval # angular.js:12811$get.Scope.$digest # angular.js:12623$get.Scope.$apply # angular.js:12915(anonymous function) # angular.js:19264jQuery.event.dispatch # jquery.js:4676jQuery.event.add.elemData.handle # jquery.js:4360
emailer.js:14 error null 0
emailer.js:16 catch Object {data: null, status: 0, headers: function, config: Object, statusText: ""}
For good measure, and since I'm new to learning Express, I'll post my server side app.js.
server/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 compression = require('compression');
var routes = require('./routes/index');
var contact = require('./routes/emailer');
var app = express();
// 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(compression());
app.use(require('connect-livereload')({
port: 35729,
ignore: ['.js']
}));
/** Development Settings */
if (app.get('env') === 'development') {
// This will change in production since we'll be using the dist folder
app.use(express.static(path.join(__dirname, '../client')));
// This covers serving up the index page
// app.use(express.static(path.join(__dirname, '../client/.tmp')));
// app.use(express.static(path.join(__dirname, '../client/public')));
// Error Handling
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
/**
* Production Settings
*/
if (app.get('env') === 'production') {
// changes it to use the optimized version for production
app.use(express.static(path.join(__dirname, '/dist')));
// 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;
app.use(function(req, res) {
res.sendfile(__dirname + '/dist/index.html');
});
Here is my file Structure:
You've definitely got some problems in your emailer.js route. You should only have routing logic there, you shouldn't be recreating your express app. Express gives you a Router object to make this easy. For example, your emailer.js could look like this:
module.exports = express.Router()
.post('/emailer', function(req,res) {
console.log(res, req, req.body, res.body);
res.json({hello:'world'});
});
And you can map this route in server/app.js like so:
var emailer = require('./routes/emailer');
// ...After all app.use statements, but *before* your error handlers
app.use('/server/routes', emailer);
Not certain, but think I have something that SHOULD work, but it doesn't, and the error I get is quite unhelpful.
So, trying to send the passport object to one of the routes, which I understand should be just to set
var users = require('./routes/users')(app, passport);
Which throws a fault on startup
> /Users/bengtbjorkberg/.nvm/versions/node/v0.12.0/bin/node app.js Test
> something 2
> /Users/bengtbjorkberg/WebstormProjects/goMinute/node_modules/express/lib/router/index.js:130
> var search = 1 + req.url.indexOf('?');
> ^ TypeError: Cannot read property 'indexOf' of undefined
> at Function.proto.handle (/Users/bengtbjorkberg/WebstormProjects/goMinute/node_modules/express/lib/router/index.js:130:27)
> at router (/Users/bengtbjorkberg/WebstormProjects/goMinute/node_modules/express/lib/router/index.js:35:12)
> at Object.<anonymous> (/Users/bengtbjorkberg/WebstormProjects/goMinute/app.js:41:38)
> at Module._compile (module.js:460:26)
> at Object.Module._extensions..js (module.js:478:10)
> at Module.load (module.js:355:32)
> at Function.Module._load (module.js:310:12)
> at Function.Module.runMain (module.js:501:10)
> at startup (node.js:129:16)
> at node.js:814:3
>
> Process finished with exit code 1
If I remove app and passport, the problem disappears magically. the routs in ./routes/users does not use any of them yet.
I have added some of the code (removed a bit of passport configuration for good form)
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 methodOverride = require('method-override'); // simulate DELETE and PUT (express4)
var stylus = require('stylus');
var nib = require('nib');
var morgan = require('morgan');
// express session and passport
var session = require('express-session');
var passport = require('passport');
var flash = require('connect-flash');
var app = express();
function compile(str, path) {
return stylus(str)
.set('filename', path)
.use(nib())
}
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
var accesslevels = require('./config/accesslevels.js');
console.log("Test something " + accesslevels.userRoles.user);
// required for passport
app.use(session({ secret: '' + 'asifIwouldtellstackoverflowright', resave: true, saveUninitialized: true })); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session
//Routes after passports
var routes = require('./routes/index');
var users = require('./routes/users')(app, passport);
var loginsrv = require('./routes/login');
var api = require('./routes/api');
var partials = require('./routes/partials');
var auth = function(req, res, next) {
if (!req.isAuthenticated())
res.send(401);
else
next();
};
//See more at: https://vickev.com/#!/article/authentication-in-single-page-applications-node-js-passportjs-angularjs
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json()); // get information from html forms
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/partials', partials);
app.use('/loginsrv', loginsrv);
//app.use(accesslevels());
//console.log(accesslevels);
// 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;
app.listen(30010);
EDIT: Added routes/users.js
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
/*
// route to test if the user is logged in or not
router.get('/loggedin', function(req, res) {
res.send(req.isAuthenticated() ? req.user : '0');
});
router.post('/login', passport.authenticate('local'), function(req, res) {
res.send(req.user);
});
router.post('/logout', function(req, res){
req.logOut();
res.send(200);
});
*/
module.exports = router;
In the above code I have changed the original router.get('/', function(req, res, next) with router.get('/', function(app, passport, req, res, next) which resolves the problem.
Just in case, if you have any HTTP verb routes app.get('/' ...) been used after app.use(..) then you will get this error in Express4x.
Ref here
I am not certain I understand why, but the trick was to changed the original router.get('/', function(req, res, next) with router.get('/', function(app, passport, req, res, next) which resolves the problem. Not certain why express requires a function that does not use the passed object to have passport and app, but it does it seems.
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(app,passport, req, res, next) {
res.send('respond with a resource');
});
/*
// route to test if the user is logged in or not
router.get('/loggedin', function(req, res) {
res.send(req.isAuthenticated() ? req.user : '0');
});
router.post('/login', passport.authenticate('local'), function(req, res) {
res.send(req.user);
});
router.post('/logout', function(req, res){
req.logOut();
res.send(200);
});
*/
module.exports = router;
app.get('/api',function(req,res)
{
if (req.url.indexOf('/api')==0) {
console.log('yes i have done it');
}
});
i Have implemented this ,I m getting output on the console.What is Happening in your code is that req is undefined.So node is throwing this error...As you can see in my code we can only only use req.url.indexOf method only when we are in scope of req.(i.e you must declare search inside function callback which handle req,res..... )