I've made a proxy using the http-proxy and express middlewares. However, it isn't forwarding PUT requests - which are essential for the application I'm proxying to. What am I doing wrong?
(The purpose of the proxy server is to provide authentication for the app behind the proxy. If there is another way to do this, I'd be grateful to know.)
var proxy = new httpProxy.RoutingProxy();
var app = express();
app.configure(function() {
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.engine('ejs', require('ejs-locals'));
app.use(express.logger());
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.session({secret: 'rupert'}));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(function(req, res) {
proxy.proxyRequest(req, res, {
host: 'localhost',
port: 8080
});
});
app.use(express.static(__dirname + '/../../public'));
});
app.get('/login', function(req, res){
res.render('login', { user: req.user, message: req.flash('error') });
});
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login', failureFlash: true }),
function(req, res) {
res.redirect('/');
});
app.get('/logout', function(req, res){
req.logout();
res.redirect('/')
});
app.all('/*', function(req, res, next) {
return next();
});
app.listen(3000,'localhost');
You can try using http-proxy's buffer function, as written here: https://github.com/nodejitsu/node-http-proxy/issues/180
Alternatively, there could be an issue with express doing non-standard things to the request object: See issue#153 at https://github.com/nodejitsu/node-http-proxy/issues/153
specifically this response from Marak:
"This is an express problem.
The Connect / Express middlewares are doing non-standard things to your response object, breaks streaming. Try using the raw request module instead of http-proxy.
If you need proper middleware stack, check out https://github.com/flatiron/union"
No idea if union will fix this, but it seems that express alters the request beyond what http-proxy can handle.
Related
I'm trying to create a website using expressjs.
I want to send a different page to the user if he's logged in.
I'm able to send the raw html website, but linked files like index.css are not beeing loaded!
app.use(cookieParser());
app.use(expressSession({secret:'somesecrettokenhere', resave: false, saveUninitialized: true}));
app.use(bodyParser());
//app.use(express.static(path.join(__dirname, '../client/login')));
// disable layout
var mainPage = express.static(path.join(__dirname, '../client/main'));
var loginPage = express.static(path.join(__dirname, '../client/login'));
app.get('/', function (req, res, next) {
console.log('getting /');
if (req.session.userName) {
//app.use(express.static(path.join(__dirname, '../client/main')));
console.log("logged in");
mainPage(req, res, next);
}else {
//app.use(express.static(path.join(__dirname, '../client/login')));
console.log("not logged in");
loginPage(req, res, next);
}
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
Thanks in advance!
Yes, you can.
You can do response.render(pageName); to render the page where you want to send the user.
app.use(cookieParser());
app.use(expressSession({secret:'somesecrettokenhere', resave: false, saveUninitialized: true}));
app.use(bodyParser());
//app.use(express.static(path.join(__dirname, '../client/login')));
// disable layout
// view engine setup
app.set('views', path.join(__dirname, '../client'));
app.set('view engine', 'jade');
app.get('/', function (req, res, next) {
console.log('getting /');
if (req.session.userName) {
//app.use(express.static(path.join(__dirname, '../client/main')));
console.log("logged in");
res.render("mainPage");
}else {
//app.use(express.static(path.join(__dirname, '../client/login')));
console.log("not logged in");
res.render("loginPage");
}
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
I used jade templating engine, you can use any other
It looks like the code you have is just checking a session for a user name -- I'd highly recommend AGAINST doing this, as it's not a secure way to do authentication.
If you want a secure way to do auth you should look into using a tool like either passportjs or stormpath. Stormpath does a bunch of stuff (api auth, social login, etc) in addition to the normal auth stuff, while passport is a bit more bare-bones.
Here's an example using Stormpath to do what you want:
app.get('/', function(req, res) {
if (req.user) {
res.render('template');
} else {
res.render('anonymousTemplate');
}
});
Full disclosure: I work # Stormpath and am the author of that library -- but it is awesome all the same.
I'd like to set up some subdomains for my Node.js app. I've built my site with express.js, and now I'd just like to throw up a little web tool on a subdomain of my site. I've tried using the vhost middleware with little luck, but am open to other approaches.
Any help would rock!
Ideally, I could just drop a new express app in a sub directory change a few lines of code, maybe change some DNS settings at it would work. The reason I'd like this is so that I can reuse a fresh instance of stylus and jade with new layouts and css styles and so forth.
Here's my normal app.js, the commented line is the attempt to use vhost.
var express = require('express'),
routes = require('./routes');
var app = module.exports = express.createServer();
// Configuration
app.configure(function() {
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.set('view options', { layout: false });
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use('/courses', function (req, res, next) {
var privates = require('./.private.json'),
couch = require('nano')('https://' + privates.dbCreds.username + ':' + privates.dbCreds.password + '#wamoyo.iriscouch.com/');
});
app.use(require('stylus').middleware({
src: __dirname + '/public'
}));
app.use(app.router);
app.use(express.static(__dirname + '/public'));
// VHOST - SUBDOMAIN
// app.use(express.vhost('adventures.innovationbound.com', require('./adventures/index').app));
app.use(function (req, res, next) {
res.status(404);
res.render('four', {
title: "Innovation Bound",
now: new Date().getFullYear()
});
});
app.use(function (err, req, res, next){
console.error(err.stack);
res.send(500, 'Something broke!');
});
});
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);
app.get('/about', routes.about);
app.get('/services', routes.services);
app.get('/events', routes.events);
app.get('/blog', routes.blog);
app.post('/contact', routes.contact);
// Courses
// app.get('/heartbeat', routes.heartbeat);
app.get('/courses', routes.courses);
// Tools
app.get('/point', routes.point);
app.listen(3000, function() {
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
});
This is using express 2.5, I wouldn't mind migrating over to 3 if need be.
I'm having some problems trying to implement some middleware in my app.
Specicially, the app.use() does not seem to catch and I don't understand why.
Below is roughly what I have.
routes/index.js
var Sessions = require('../events');
module.exports = exports = function(app) {
app.use(Sessions.isLoggedIn);
//app.use() does not catch but this does
//app.all('*', Sessions.isLoggedIn);
// Home Page
app.get('/', displayHome);
app.get('/:library/:books', displayLibrary);
}
events.js
module.exports = exports = {
isLoggedIn: function(req, res, next) {
console.log('isLoggedIn');
return next();
}
Any suggestions as to why app.use() is not catching?
UPDATE:
Here is the configuration in ape.js
app.configure(function() {
app.set('port', process.env.VCAP_APP_PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.logger('dev'));
app.use(express.compress()); // compress responses
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(expressValidator);
app.use(express.cookieParser('locket'));
app.use(express.cookieSession({
key: 'locket',
secret: 'mySecret',
cookie: {httpOnly: true, expires: 0, path: '/'}
}));
// cache every file going out
app.use(function(req, res, next) {
if (!res.getHeader('Cache-Control')) {
res.setHeader('Cache-Control', 'public, max-age=' + (86400 / 1000));
}
next();
});
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use(express.errorHandler({showStack: true, dumpExceptions: true}));
});
routes(app);
The router is responding to the request before your middleware function has a chance to run.
app.js sets up several other middleware functions, then uses app.router. You then call your routes/index.js file, which uses a new middleware function which gets added after app.router.
use your isLoggedIn function before the router, or use it specifically with the routes that need to check login state:
app.get('/', Sessions.isLoggedIn, function(req, res) { ... });
As far as I can tell I'm configuring my global middleware function as described in the docs and in every forum post on the subject, but it is not being called. Does anyone see what I'm doing wrong? express 3.2.5. In the log output I see the following:
Express server listening on port 9000
inside route
GET / 200 7ms - 2b
I expect to see "inside middleware", then "inside route". Instead, I just see "inside route".
The code:
var express = require('express'), http=require('http'), path=require('path');
var app = express();
app.enable('trust proxy');
app.set('port', process.env.PORT || 9000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.set('layout', 'layout');
app.use(require('express-ejs-layouts'));
app.use(express.favicon(__dirname + '/public/images/favicon.ico'));
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride())
app.use(express.cookieParser('kfiwknks'));
app.use(express.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
if ('development' == app.get('env')) {
app.use(express.errorHandler());
} else {
app.use(function(err, req, res, next){
console.error (error);
res.send (500, "Internal server error");
});
}
app.use (function (req, res, next) {
console.log ("inside middleware");
next();
});
app.get ("/", function (req, res) {
console.log ("inside route");
res.send(200);
});
http.createServer(app).listen(app.get('port'), function() {
console.log('Express server listening on port ' + app.get('port'));
});
This related post:
Express 3 error middleware not being called
is specific to error handling middleware. Mine is a vanilla middleware.
You should put your middleware before you use app.router.
...
app.use (function (req, res, next) {
console.log ("inside middleware");
next();
});
...
app.use(app.router);
Updated answer for Express 4 users from the Express 4 docs. See example from docs below. Note that app.router is deprecated and no longer used. I also added a dummy route to make the ordering clear.
You define error-handling middleware last, after other app.use() and routes calls
Example:
var bodyParser = require('body-parser');
app.use(bodyParser());
app.get('/', function(req, res) {
res.send('hello world');
})
app.use(function(err, req, res, next) {
// logic
});
newbie.
I'm using ExpressJS/Node. Here's my config stuff:
var express = require('express'),
app = express.createServer(),
jade=require('jade');
// Configuration
app.configure(function(){
app.set('views', __dirname + '/views');
app.use(express.logger());
app.use(express.cookieParser());
app.use(express.session({ secret: "secretive secret" }));
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(require('stylus').middleware({ src: __dirname + '/public' }));
app.use(app.router);
app.use(express.static(__dirname + '/public'));
app.use(express.csrf());
I found csrf.js in Express directories, and see that it should be generated and assigned to req.body._csrf, but I'm not sure how to access it.
Here's the csrf.js code
module.exports = function csrf(options) {
var options = options || {}
, value = options.value || defaultValue;
return function(req, res, next){
// generate CSRF token
var token = req.session._csrf || (req.session._csrf = utils.uid(24));
// ignore GET (for now)
if ('GET' == req.method) return next();
// determine value
var val = value(req);
// check
if (val != token) return utils.forbidden(res);
next();
}
};
Help? Thanks!
Dynamic helpers has been removed from Express since 3.x.
The new usage would be app.use(express.csrf());, which comes from Connect.
Add the token to dynamic helpers.
app.dynamicHelpers({
token: function(req, res) {
return req.session._csrf;
}
});
Reference it in your jade template.
input(type='hidden', value=token)
Source: http://senchalabs.github.com/connect/middleware-csrf.html
In Express 4.x this middleware is removed. For Express 4.x you can do it as follows
var csrf = require('csurf');
app.use(csrf());
Ah!! you need to register the csrf middleware after your session and cookieParser middleware.
Inside Route Or Ctrl
res.render('someform', { csrf: req.csrfToken() });
or You can set a local variable also like so
app.use(function(req, res, next){
res.locals.csrf = req.csrfToken();
});
Then in view
input(type="hidden", name="_csrf", value="#{csrf}")
You are done!! :)
If you also want to set a secure cookie for your CSRF token that can be read by your frontend (angular for example), you can do this:
app.use csrf()
app.use (req, res, next) ->
res.cookie('XSRF-TOKEN', req.csrfToken(), {secure: true})
next()