how to send file in nodejs, i am creating one page app, so i just want abcd.html page to be delivered on request for first time,
here is my code to that
app.js
var express = require('express'),
app = express(),
http = require('http'),
path = require('path'),
fs = require('fs'),
mysql = require('mysql'),
server = http.createServer(app),
passport = require('passport'),
flash = require('connect-flash'),
useragent = require('express-useragent'),
io = require('socket.io').listen(server);
// configuration ===============================================================
// connect to our database
require('./config/passport')(passport); // pass passport for configuration
app.use(express.static(path.join(__dirname, 'public')));
app.use(app.router);
app.configure(function() {
app.set('views', path.join(__dirname, 'app/views'));
app.set('view engine', 'ejs'); // set up ejs for templating
// required for passport
app.use(express.session({secret: 'vidyapathaisalwaysrunning',key: 'myuser.sid',cookie: { secure: false,maxAge:null}} )); // session secret1
//app.use(express.session({secret: 'vidyapathaisalwaysrunning', key: 'myownsid', cookie: { secure: false, maxAge: 3600000 }} )); // session with expitation
//app.use(express.session({ key: 'express.sid', secret: 'vidyapathaisalwaysrunning' } )); // 2 cookieId ie connect.sid & express.sid(user defined) session secret1
//app.use(express.session({ store: sessionStore, secret: 'vidyapathaisalwaysrunning',cookie: {httpOnly: false},key: 'cookie.sid' } )); // session secret
// set up our express application
app.use(express.logger('dev')); // log every request to the console
app.use(express.cookieParser()); // read cookies (needed for auth)
app.use(express.bodyParser()); // get information from html forms
app.use(useragent.express());
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session
app.use(express.static(path.join(__dirname, 'public')));
});
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
//routes ======================================================================
require('./app/controller.js')(app, passport,io); // load our routes and pass in our app and fully configured passport
//require('./app/socket')(app,io);
// launch ======================================================================
server.listen(8080);
response to the page
case '/':
/*response.writeHead(200, {'Content-Type': 'text/html'});
response.write('hello world');*/
//response.json({ message: 'hello' });
response.sendfile("../public/abcd.html");
break;
it always gives Can't set headers after they are sent, here is the console output
Error: Forbidden
at SendStream.error (/home/pitu/CODING/NODE-PROJECTS/chichat/node_modules/express/node_modules/send/lib/send.js:145:16)
at SendStream.pipe (/home/pitu/CODING/NODE-PROJECTS/chichat/node_modules/express/node_modules/send/lib/send.js:307:39)
at ServerResponse.res.sendfile (/home/pitu/CODING/NODE-PROJECTS/chichat/node_modules/express/lib/response.js:339:8)
at /home/pitu/CODING/NODE-PROJECTS/chichat/app/controller.js:18:21
at callbacks (/home/pitu/CODING/NODE-PROJECTS/chichat/node_modules/express/lib/router/index.js:161:37)
at param (/home/pitu/CODING/NODE-PROJECTS/chichat/node_modules/express/lib/router/index.js:135:11)
at pass (/home/pitu/CODING/NODE-PROJECTS/chichat/node_modules/express/lib/router/index.js:142:5)
at Router._dispatch (/home/pitu/CODING/NODE-PROJECTS/chichat/node_modules/express/lib/router/index.js:170:5)
at Object.router (/home/pitu/CODING/NODE-PROJECTS/chichat/node_modules/express/lib/router/index.js:33:10)
at next (/home/pitu/CODING/NODE-PROJECTS/chichat/node_modules/express/node_modules/connect/lib/proto.js:190:15)
_http_outgoing.js:331
throw new Error('Can\'t set headers after they are sent.');
^ Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:331:11)
at ServerResponse.res.setHeader (/home/pitu/CODING/NODE-PROJECTS/chichat/node_modules/express/node_modules/connect/lib/patch.js:59:22)
at /home/pitu/CODING/NODE-PROJECTS/chichat/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js:63:17
at fs.js:292:14
at Object.oncomplete (fs.js:93:15)
refrence screenshot
what to do
var event= require('./models/event');
var url = require('url');
var fs = require("fs");
//var app1 = require('../../app').app;
module.exports = function(app, passport,io)
{
//app.get('/createevent',event.createevent);
app.get('*', function(request, response)
{
var path = url.parse(request.url).pathname;
//use request object to get user data
//response.render('index');
switch(path){
case '/':
/*response.writeHead(200, {'Content-Type': 'text/html'});
response.write('hello world');*/
//response.json({ message: 'hello' });
//response.sendfile('../../public/abcd.htm', {root: __dirname })
response.sendfile('./public/abcd.htm');
break;
case '/creteevent':
console.log(" inside createevent ");
response.render('index123',{ title: 'The index page!' });
break;
case '/eventmember':
//response.render('index');
//this method is good becz below code , calling same as 4 both socket & http req
event.eventmember(function(err,returnedvalue)
{
if(returnedvalue){
console.log(" member result "+returnedvalue);
response.json(returnedvalue);
}else{
console.log(" member err "+ err);
}
});
break;
case '/eventtags':
var str = '{"eventid" :"2","associatedtags":["2","3"]}';
//response.render('index');
//this method is good becz below code , calling same as 4 both socket & http req
event.eventtags(str,function(err,returnedvalue)
{
if(returnedvalue){
console.log(" post result "+returnedvalue);
}else{
console.log(" posting err "+ err);
}
});
break;
case '/post':
var str = '{"eventid" :"2","selfid" :"2","title" :"feeedback to event","content" :"bla bla bla","lattitude" :"","longitude" :"","createddatetime" :"","posttype" :"idea","isapporved" :"no","isanonymous" :"no"}';
//response.render('index');
//this method is good becz below code , calling same as 4 both socket & http req
event.post(str,function(err,returnedvalue)
{
if(returnedvalue){
console.log(" post result "+returnedvalue);
}else{
console.log(" posting err "+ err);
}
});
break;
default:
response.writeHead(404);
response.write("opps this doesn't exist - 404");
break;
}
//just remove this line,& it worked, becz 2 response for a single request
***response.end();***
});
};
Related
My index.js Server
// USE STRICT;
const express = require('express');
const app = express();
const session = require('express-session');
const http = require('http').Server(app);
const socket = require('socket.io');
const schedule = require('node-schedule');
const cors = require('cors');
const io = socket(http, {
cors: {
origin: 'http://localhost:8080',
methods: ['GET', 'POST'],
allowedHeaders: ['my-custom-header'],
credentials: true
}
});
const port = 8080;
app.use(express.static(__dirname + '/public'));
app.use(express.static(__dirname + '/uploads'));
const cookieParser = require('cookie-parser');
const csrf = require('csurf');
const mustacheExpress = require('mustache-express');
app.engine('html', mustacheExpress());
app.set('view engine', 'html');
app.set('views', __dirname + '/views');
const secret = 'somesecretkeyhere';
const passport = require('passport');
const helmet = require('helmet');
const { sendMail } = require('./controllers/sellerAdsController');
// Gives us access to variables set in the .env file via `process.env.VARIABLE_NAME` syntax
// require('dotenv').config();
// Must first load the models before passport
require('./models/user');
// Pass the global passport object into the configuration function
require('./config/passport')(passport);
// This will initialize the passport object on every request
app.use(passport.initialize());
// Allows our remote applications to make HTTP requests to Express application
app.use(cors());
app.use(helmet());
app.use(express.urlencoded({ extended: false }));
// app.use(express.json()); //WARNING: Do not turn on. stops formidable for api calls
app.use(cookieParser(secret));
app.use(session({
secret: secret,
resave: false,
saveUninitialized: true,
cookie: {
httpOnly: true,
secure: true
}
}));
app.use(csrf());
// Stop page caching
app.use(function (req, res, next) {
res.set('Cache-Control', 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0');
next();
});
// Imports all of the routes from ./routes/index.js
app.use(require('./routes/api/v1'));
// Socket Operations
// io.on('connection', io => {
// let sessionId = io.id;
// io.on('clientHandshake', (data) => {
// console.log(data);
// io.emit('serverHandshake', { sessionId: sessionId });
// });
// });
// io.use((socket, next) => {
// const username = socket.handshake.auth.username;
// if (!username) {
// return next(new Error('invalid username'));
// }
// console.log(username);
// socket.username = username;
// next();
// });
io.on('connection', (socket) => {
console.log('👾 New socket connected! >>', socket.id);
// notify existing users
socket.broadcast.emit('user connected', {
userID: socket.id,
username: socket.username,
});
socket.on('private message', ({ content, to }) => {
socket.to(to).emit('private message', {
content,
from: socket.id,
});
console.log(content, to);
});
});
// EROOR HANDLING ROUTES MUST BE BENEATH ALL APP.USE AND ROUTES
// Check if request is from web or app (HTML/JSON)
// Handle 404
app.use(function (req, res) {
res.status(404);
res.render('404.html', { title: '404: File Not Found' });
});
// Handle 500
app.use(function (error, req, res) {
return res.send(error);
// res.status(500);
// res.render('500.html', { title: '500: Internal Server Error', error: error });
});
// SCHEDULED JOBS
const now = new Date();
let date = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 0, 0);
schedule.scheduleJob(date, sendMail);
http.listen(port, () => {
console.log(`listening on *:${port}`);
});
And this is how I am getting from VUE
window.axios.get('/databank/getCSRF').then((response) => {
window.axios.defaults.headers.common['XSRF-TOKEN'] = response.data;
}, (err) => {
console.log(err)
})
And this is my login request header
XSRF-TOKEN from my login request header sent by axios
So Ive set my server up like that, and my vue SPA, but getCSRF() seems to be getting the request but I can't do a POST request back to the server throws an error
ForbiddenError: invalid csrf token
at csrf
Maybe because you wrote XSRF-TOKEN instead of CSRF-Token as it suggests in the Express Documentation.
I created two post api in nodejs one is login and another one is dashboard api. I want to send the email, role data from login api to dashboard api.Can anyone give me the solution for this problem?Advance Thankyou for your answer.
var express = require("express");
var session = require("express-session");
var bodyParser = require("body-parser");
var app = express();
app.engine('html', require('ejs').renderFile);
app.use(session({
secret: 'JILLU',
cookie:{maxAge:60*60*24*1000},
resave: false,
saveUninitialized: false
}));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.post('/login',function(req,res,next){
var ses = req.session;
ses.id=req.session.id;
ses.email=req.body.mailid;
ses.role=req.body.role;
console.log(ses.id);
res.redirect(307,'/dashboard');
});
app.post('/dashboard',function(req,res){
console.log("dashboard");
if(ses.email) {
console.log("email is a live");
console.log(ses.email);
console.log(ses.role);
console.log(ses.id);
res.write(ses.email);
res.write(ses.role);
} else {
console.log("login first");
res.render(__dirname+"/mailrequest.html");
}
});
app.listen(8086,function(){
console.log("App Started on PORT 8086");
});
This should work,
// '/login'
app.post('/login',function(req,res,next){
var ses = req.session;
ses.email=req.body.mailid;
ses.role=req.body.role;
console.log(ses.id);
res.redirect(307,'/dashboard');
});
// '/dashboard'
app.post('/dashboard',function(req,res){
console.log("dashboard");
if(req.session.email) {
console.log("email is a live");
console.log(req.session.email);
console.log(req.session.role);
console.log(req.session.id);
res.write(req.session.email);
res.write(req.session.role);
} else {
console.log("login first");
res.render(__dirname+"/mailrequest.html");
}
});
The problem was that the variable ses was local and was undefined in '/dashboard' route whereas session is an object of the req(request) object.
And I suggest you to use http get request for dashboard instead of post.
I am trying to implement csrf protection into my project but I can't make it work with jQuery Ajax. (It works with normal posts requests, though)
If I tamper the token using chrome dev tools before I send the form, I still see "data is being processed" text rather than invalid csrf token error.
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 csrf = require('csurf');
var bodyParser = require('body-parser');
var router = express.Router();
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
//app.set('strict routing', true);
app.set('view options', {layout: false});
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser());
var csrfProtection = csrf({ cookie: true });
var parseForm = bodyParser.urlencoded({ extended: false });
app.use(express.static(path.join(__dirname, 'public')));
app.get('/form', csrfProtection, function(req, res) {
// pass the csrfToken to the view
res.render('send', { csrfToken: req.csrfToken() });
});
app.post('/form', parseForm, csrfProtection, function(req, res) {
res.send('data is being processed');
});
// 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;
send.jade
html
head
meta(name='_csrf', content='#{csrfToken}')
body
form(action='/form', method='POST')
| Favorite color:
input(type='text', class="favori", name='favoriteColor')
button(type='submit') Submit
script(src="javascripts/frontend/jquery/jquery-3.0.0-alpha1.js")
script(src="javascripts/test.js")
test.js
$(document).ready(function () {
$.ajaxSetup({
headers: {'X-CSRF-Token': $('meta[name="_csrf"]').attr('content')}
});
$('button').click(function (e) {
e.preventDefault();
var text = $('.favori').val();
alert(text);
$.post(
"/form",
{
text: text
}, function (data) {
console.log(data);
});
});
});
Send the CSRF token inside the payload message:
$('button').click(function (e) {
e.preventDefault();
var text = $('.favori').val();
alert(text);
$.post(
"/form",
{
text: text,
_csrf : $('meta[name="_csrf"]').attr('content')
}, function (data) {
console.log(data);
});
});
To facilitate your work I think you can create a Jquery plugin to do it, something like this:
(function( $ ) {
$.postCSRF = function(to, message, callback) {
message._csrf = $('meta[name="_csrf"]').attr('content');
$.post(to, message, callback);
};
}( jQuery ));
// Usage example:
$.postCSRF('/form',{text:'hi'},function(res) {
console.log(res);
});
Example: http://jsfiddle.net/w7h4Lkxn/
Check the header to see if its passing the tampered token in the cookie or as part of the form data. It looks like your setup is for using cookies. So changing it on the form shouldn't affect the cookie. Lemme know if that helps reveal the issue.
your doing everything exactly right but you have to disable checking for the cookie entirely!
var csrfProtection = csurf({ cookie: false });
the author mentions it here
https://github.com/expressjs/csurf/issues/52
thanks for the above code with the header post as this was crucial for validating the express session token and i have shared it with others
Using connect, express, and socket.io, I'm trying to allow my application to grab the session details when reconnecting. My sessions obviously work while the client is connected, but if I refresh the page on my browser, it forgets everything.
My session cookie is definitely the same, so it's not that.
My code's a big mish-mash of snippets I've taken from a number of different sources, since there doesn't seem to be one complete example application out there. :-/
What am I missing..?
var qs = require('querystring'),
express = require('express'),
app = express.createServer(),
io = require('socket.io').listen(app.listen(8000)),
routes = require('./routes'),
pCookie = require('connect').utils.parseCookie,
Session = require('connect').middleware.session.Session,
RedStore= require('connect-redis')(express),
sStore = new RedStore();
// Configuration
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({ store: sStore, secret: 'tehsecretz' }));
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
// Routes
app.get('/', routes.index);
io.sockets.on('connection', function (client) {
var hs = client.handshake,
session = hs.session;
console.log('A socket connected called: ' + hs.sessionId);
var intervalId = setInterval(function() {
hs.session.reload(function() {
hs.session.touch().save();
});
}, 60 * 1000);
if (!session.userName) {
// Prompts the user for a name on the frontend
client.emit('need-to-register');
}
client.on('message', function(msg, c) {
console.log(session);
console.log(msg);
});
client.on('register-user', function(data, fn) {
// This retrieves the user's name
// and - hopefully - saves it to the session.
data = qs.parse(data);
session.userName = data.username;
hs.session.save();
console.log('Saving: ', session);
fn('ok');
});
client.on('disconnect', function() {
clearInterval(intervalId);
});
});
io.set('authorization', function (data, accept) {
if (data.headers.cookie) {
data.cookie = pCookie(data.headers.cookie);
data.sessionId = data.cookie['connect.sid'];
data.sessionStore = sStore;
sStore.get(data.sessionId, function (err, session) {
if (err || !session) {
accept('Error', false);
} else {
console.log(data.sessionId, session);
data.session = new Session(data, session);
accept(null, true);
}
});
} else {
return accept('No cookie transmitted', false);
}
});
Thanks for any help provided!
Ugh. So in Daniel Baulig's post on the subject, he referenced the identifier sessionID. I figured that was just poor convention (as I'm used to camelCase) and promptly changed it to sessionId in my code.
As I was debugging, I turned on MONITORing on my redis instance and noticed the session was being written to sess:undefined.
Turns out sessionID is special and is referenced internally as the actual identifier. Changing all instances of sessionId to sessionID allows me to have a better clue as to who is connecting!
Add 'cookie' in "express.session"
app.use(express.session({
secret: 'exampleSecretKey'
,store: exampleStore
,key: 'example'
cookie: {
path: '/'
,expires: false // Alive Until Browser Exits
,httpOnly: true
// ,domain:'.example.com'
}
});
Question:
Is it possible to store session data similar to $_SESSION['somedata'] = "Hello" in php?
Here is my code so far:
Creating the memory store
var MemoryStore = express.session.MemoryStore,
sessionStore = new MemoryStore();
Express Config
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({
store: sessionStore,
secret: 'secret',
key: 'express.sid'}));
app.use(require('stylus').middleware({src: __dirname + '/public'}));
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
Parsing the cookie to get the session id on handshake authorization
var parseCookie = require('connect').utils.parseCookie;
io.set('authorization', function (data, accept) {
if (data.headers.cookie) {
data.cookie = parseCookie(data.headers.cookie);
data.sessionID = data.cookie['express.sid'];
sessionStore.get(data.sessionID, function (err, session) {
if (err)
{
accept(err.message, false); //Turn down the connection
}
else
{
data.session = session; //Accept the session
accept(null, true);
}
});
} else {
return accept('No cookie transmitted.', false);
}
});
Storing 'loggedin' when the password and username are 'admin'
io.sockets.on('connection', function (socket) {
socket.on('details', function(data){
console.log("Details: " + data.u + data.p);
if(data.p == "admin" && data.u == "admin")
{
//Add the logged in field to the session
}
});
});
If the user is logged in redirect them to the home page
app.get(navigation.login.uri, function(req, res){
if(req.session.loggedin)
{
res.redirect('/home');
}
else
{
res.render('login', {
title: navigation.login.title,
navigation: navigation
});
}
});
When I try to use:
req.session.loggedIn
The value is undefined. Could this be a storage problem, or am I accessing it incorrectly?
You're close - just missing a couple of things.
The information that you are gathering in the socket authorization function is accessible via socket.handshake in your connection handler.
So, what I think you want is:
io.sockets.on('connection', function (socket) {
socket.on('details', function(data){
console.log("Details: " + data.u + data.p);
if(data.p == "admin" && data.u == "admin")
{
//Add the logged in field to the session
socket.handshake.session.loggedIn = true; // Set the new session var
socket.handshake.session.save(); // Save the modified session
}
});
});
Don't forget to save the session after modifying it otherwise it never gets back into the store.
This worked for me - you basically just have to set a key in the sessionStore:
io.sockets.on('connection', function (socket) {
socket.on('details', function(data){
console.log("Details: " + data.u + data.p);
if(data.p == "admin" && data.u == "admin")
{
// set the value
sessionStore.loggedIn = true;
// get the value
console.log(sessionStore.loggedIn);
}
});
});
I tried it on a website with some subpages, the value was consistent. A forced reload or closing the browser resets it.