A Newbie question I guess. I want to set and get cookies on my express site.
cookieParser is set up and seems to run. But my cookies are always undefined. So what can be wrong? Doesn't cookies work on localhost?
I can access all cookies in the console on chrome.
I have tried both httpOnly: false/true.
Here's my code:
var express = require('express'),
exphbs = require('express-handlebars'),
bodyParser = require('body-parser'),
cookieParser = require('cookie-parser'),
request = require('request'),
livereload = require('express-livereload'),
port = Number(process.env.PORT || 3000);
var log = require('./lib/log.js'));
var app = express();
livereload(app, config = {watchDir: process.cwd()});
app.engine('handlebars', exphbs({defaultLayout: 'main'}));
app.set('view engine', 'handlebars');
app.use(express.static('public'));
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true}));
app.get('/', function(req, res) {
res
.cookie('cart', 'test', {maxAge: 900000, httpOnly: false})
.render('index');
console.log(res.cookie.cart);
});
app.listen(port, function() {
log.clear();
log.out('Express on http://localhost:' + port);
log.hr();
});
Any clues?
Maybe you should change:
console.log(res.cookie.cart);
to:
console.log(req.cookies.cart);
I just wrote a simple example that demonstrates what's going on:
var express = require('express');
var cookieParser = require('cookie-parser');
var app = express();
app.use(cookieParser());
app.get('/', function(req, res) {
var oldCookie = req.cookies.test;
var newCookie = (oldCookie|0) + 1;
res.cookie('test', newCookie, {maxAge: 900000});
res.status(200).json({
newCookie: newCookie,
oldCookie: oldCookie,
reqCookie: req.cookies.test,
});
});
app.listen(3000, function () {
console.log('Listening on http://localhost:3000/');
});
When you run it and go with your browser to http://localhost:3000/ you will see:
{"newCookie":1}
When you reload the page you will see:
{"newCookie":2,"oldCookie":"1","reqCookie":"1"}
Here's what's going on: In the first request even though you set the cookie in you handler before printing it it is not really set yet - it is just queued to be passed to the client in the response with an HTTP header like this one:
Set-Cookie: test=1; Max-Age=900; Path=/; Expires=Wed, 21 Sep 2016 13:03:06 GMT
In the second request you see the old value in reqCookie and the new value in newCookie - those values are different. Seeting the cookie doesn't change the one that you got in the request. I even included the reqCookie which is not stored in a variable but accessed directly from req.cookies during the res.end() invocation to demonstrate that it is not changed.
Related
I am writing a simple MEAN app, and I am currently working on the routes.
In my server.js, I have
var express = require('express');
var multer = require('multer');
var upload = multer({dest: 'uploads/'});
var sizeOf = require('image-size');
var app = express();
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
// configuration ===========================================
require('./app/models/Purchase');
require('./app/models/Seller');
require('./app/models/User');
// config files
var db = require('./config/db');
var port = process.env.PORT || 8080; // set our port
// mongoose.connect(db.url); // connect to our mongoDB database
// get all data/stuff of the body (POST) parameters
app.use(bodyParser.json()); // parse application/json
app.use(bodyParser.json({ type: 'application/vnd.api+json' })); // parse application/vnd.api+json as json
app.use(bodyParser.urlencoded({ extended: true })); // parse application/x-www-form-urlencoded
app.use(methodOverride('X-HTTP-Method-Override')); // override with the X-HTTP-Method-Override header in the request. simulate DELETE/PUT
app.use(express.static(__dirname + '/public')); // set the static files location /public/img will be /img for users
// routes ==================================================
var routes = require('./app/routes/routes');//(app); // pass our application into our routes
var price = require('./app/routes/pricing');
var processing = require('./app/routes/processing');
var uploads = require('./app/routes/uploads');
var seller = require('./app/routes/seller');
app.use('/', routes);
app.use('/price', price);
app.use('/processing', processing);
app.use('/uploads', uploads);
app.use('/seller', seller);
// start app ===============================================
app.listen(port);
console.log('Magic happens on port ' + port);
exports = module.exports = app;
Then, in my route, I have
var express = require('express');
var mongoose = require('mongoose');
var Seller = mongoose.model('Seller');
var router = express.Router();
router.get('/', function(req,res){
res.json({message: 'youre in router.get'});
});
router.post('/registerSeller', function(req,res,next){
console.log('You made it all the way to seller route!');
res.json({message: "you did it"});
next();
});
module.exports = router;
When I start my node server, everything goes well. When I use Postman to POST to the above route, it just 'hangs' and eventually gives an error message that it cannot connect. In Postman, I select 'POST' to http://localhost:8080/seller/registerSeller.Clicking 'code', I get
POST /seller/registerSeller HTTP/1.1
Host: localhost:8080
Cache-Control: no-cache
Postman-Token: 070cb9b3-992a-ffd6-cede-c5b609bc9ce5
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Looking at the browser's developer tools, it shows a POST being made, and then after a while, it also reads that the POST failed.
Could anyone tell me what I'm doing wrong? Thank you.
The problem is that you are responding and then trying to call the next() function in the router stack.
router.post('/registerSeller', function(req,res,next){
console.log('You made it all the way to seller route!');
return res.send({message: "you did it"});
//next(); remove this shit.
});
This should work. Express middlewares go in order. So if you need to have a middleware to be called before this function, then you have to put it before in the stack. If you need to do something after this function, forget about the res.json... part.
I am having an issue where I am getting the following error code when attempting a POST request on this application (bearing in mind I am a beginner node.js/js programmer):
Error:
[20:22:28] [nodemon] starting `node app.js`
Running server on 3000
Mon, 27 Jun 2016 19:22:31 GMT express deprecated res.send(status, body): Use res.status(status).send(body) instead at routes\edit.js:35:25
c:\Users\Matt\WebstormProjects\ghs_restart\node_modules\mongodb\lib\utils.js:98
process.nextTick(function() { throw err; });
^
RangeError: Invalid status code: 0
at ServerResponse.writeHead (_http_server.js:192:11)
at ServerResponse._implicitHeader (_http_server.js:157:8)
at ServerResponse.OutgoingMessage.end (_http_outgoing.js:573:10)
at ServerResponse.send (c:\Users\Matt\WebstormProjects\ghs_restart\node_modules\express\lib\response.js:204:10)
at ServerResponse.json (c:\Users\Matt\WebstormProjects\ghs_restart\node_modules\express\lib\response.js:249:15)
at ServerResponse.send (c:\Users\Matt\WebstormProjects\ghs_restart\node_modules\express\lib\response.js:151:21)
at c:\Users\Matt\WebstormProjects\ghs_restart\routes\edit.js:35:25
at c:\Users\Matt\WebstormProjects\ghs_restart\node_modules\mongodb\lib\collection.js:416:18
at handleCallback (c:\Users\Matt\WebstormProjects\ghs_restart\node_modules\mongodb\lib\utils.js:96:12)
at c:\Users\Matt\WebstormProjects\ghs_restart\node_modules\mongodb\lib\collection.js:705:5
app.js:
var express = require('express');
var router = express.Router();
var app = express();
var bodyParser = require('body-parser');
app.use( bodyParser.json() ); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
var path = require('path');
var port = process.env.PORT || 3000;
var index = require('./routes/index');
var edit = require('./routes/edit');
app.use('/', index);
app.use('/edit', edit);
app.use(express.static(path.join(__dirname, 'public')));
app.set('view engine', 'jade');
app.set('views', 'views');
app.listen(port, function (err) {
console.log("Running server on", port);
});
module.exports = index;
The following is my edit.js route, where I believe the issue is occurring:
var express = require('express');
var router = express.Router();
var app = express();
var bodyParser = require('body-parser');
app.use( bodyParser.json() ); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
var path = require('path');
var port = process.env.PORT || 3000;
var index = require('./routes/index');
var edit = require('./routes/edit');
app.use('/', index);
app.use('/edit', edit);
app.use(express.static(path.join(__dirname, 'public')));
app.set('view engine', 'jade');
app.set('views', 'views');
app.listen(port, function (err) {
console.log("Running server on", port);
});
module.exports = index;
I had a similar error message just now and managed to solve the problem by changing:
res.status(statusCode);
to:
if (statusCode >= 100 && statusCode < 600)
res.status(statusCode);
else
res.status(500);
or just:
res.status(statusCode >= 100 && statusCode < 600 ? err.code : 500);
I.e. make sure you aren't trying to set an invalid HTTP status code somewhere.
It's likely this is the issue but it looks like you've accidentally duplicated the app.js code instead of pasting the edit.js code in the question.
This case also happen when we have validation error on form save and we are using res.redirect instead of res.render method
for example-
Please Use
res.render('users/add', {
countries: countries
});
instead of (it's wrong statement for node)
res.redirect('/users/add', {
countries: countries
});
I had the same problem which I solved by using:
res.send('0')
instead of
res.send(0)
for me the issue was that i had not created my upload directory and it returns me the error. may be you should consider to create your ./upload directory first, because of permission issues on linux.
I'm trying to follow this tutorial, in which the author provides a sample code:
// server.js
// BASE SETUP
// =============================================================================
// call the packages we need
var express = require('express'); // call express
var app = express(); // define our app using express
var bodyParser = require('body-parser');
// configure app to use bodyParser()
// this will let us get the data from a POST
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var port = process.env.PORT || 8080; // set our port
// ROUTES FOR OUR API
// =============================================================================
var router = express.Router(); // get an instance of the express Router
// test route to make sure everything is working (accessed at GET http://localhost:8080/api)
router.get('/', function(req, res) {
res.json({ message: 'hooray! welcome to our api!' });
});
// more routes for our API will happen here
// REGISTER OUR ROUTES -------------------------------
// all of our routes will be prefixed with /api
app.use('/api', router);
// START THE SERVER
// =============================================================================
app.listen(port);
console.log('Magic happens on port ' + port);
And I tweaked it a little bit and here is my code:
'use strict';
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var port = process.env.PORT || 8081;
var router = express.Router();
router.get('/', function(req, res, next) {
res.json({ message: 'Hello World!' });
});
app.use('/api', router);
app.listen(port);
console.log('Magic happens on port ' + port);
The server runs perfectly but when I visit localhost:8081, I get the following message on my browser: Cannot GET /
What am I doing wrong here?
Since you added app.use('/api', router);
And your route is router.get('/', function(req, res, next) { res.json({ message: 'Hello World!' }); });
Then to access '/' you need to request with /api/
Update: If you have set the port on in env use that port or else you should be able to access using localhost:8081/api/
Hope it helps !
The above comment is correct.
You have added prefix '/api' to your local server and all incoming request will be http://localhost:<port>/api/<path>
app.use('/api', router);
If you want to access like this (without prefix) http://localhost:<port>/<path>
Please update your code to
app.use(router);
I'm trying to verify a signed token and extract information from it using NodeJS.
I have a token named userToken in the browser right now, it has been saved after I logged in (I use auth0 to login by the way).
I tried to verify my token here manually : http://jwt.io , it works and gives me payload data without a problem. However, I can't do the same thing with NodeJS. How can I do it?
I read the docs but I couldn't get it.
https://github.com/auth0/express-jwt
Here's my server.js
var http = require('http');
var express = require('express');
var cors = require('cors');
var app = express();
var jwt = require('express-jwt');
var dotenv = require('dotenv');
dotenv.load();
var authenticate = jwt({
secret: new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64'),
audience: process.env.AUTH0_CLIENT_ID
});
// view engine setup
var path = require('path');
app.set('views', path.join(__dirname, 'views'));
app.use(express.static(path.join(__dirname, 'public')));
app.set('view engine', 'jade');
app.configure(function () {
// Request body parsing middleware should be above methodOverride
app.use(express.bodyParser());
app.use(express.urlencoded());
app.use(express.json());
app.use(cors());
app.use(app.router);
});
app.get('/', function (req, res) {
res.render('index');
});
app.get('/test', function(req,res) {
// how do I check it?
});
var port = process.env.PORT || 3001;
http.createServer(app).listen(port, function (err) {
console.log('listening in http://localhost:' + port);
});
You dont't need to implement nothing. Since you are using this express-jwt, just pass the userProperty tag to jwt:
var authenticate = jwt({
secret: new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64'),
audience: process.env.AUTH0_CLIENT_ID,
userProperty: 'payload'
});
So, you can get all of your jwt payload data using req.payload in your controllers. You can check it with console.log(req.payload).
You can see how it works here: https://github.com/auth0/express-jwt/blob/master/lib/index.js#L121
I hope it helps, and sorry about my English.
This sample should help you, it's not tested, but sure it's right way, look at source of express-jwt, it does literally same behind the scenes
app.get('/test', function(req, res) {
var jsonwebtoken = require('jsonwebtoken'); //install this, move to declarations
var loginToken = req.headers.authentication || req.body.userToken || req.headers.Bearer; //or your own, it's just headers that pass from browser to client
jsonwebtoken.verify(loginToken, new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64'), function(err, decoded) {
if(err) {
return res.status(401).send({message: 'invalid_token'});
}
//be aware of encoded data structure, simply console.log(decoded); to see what it contains
res.send(decoded); //`decoded.foo` has your value
});
});
The thing is that you must yourself encode your data, and then decode, so be aware that auth0 returns valid data structure for you (as i'm not sure otherwise)
I am finding a trouble to set a session with node.js using express4.2.0 I show you my code and after I comment:
APP.js
var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var cookieSession = require('cookie-session');
var mainModel = require('./model/main_model');
var users = require('./routes/users');
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieSession({
keys: ['secret1', 'secret2']
}));
app.use('/users', users);
/*Evething that express makes automatically*/
app.listen(8080);
USERS.js
var express = require('express');
var router = express.Router();
router.get('/', function(req, res)
{
if(req.cookie && req.cookie.user) res.send("COOKIE");
else if(req.session && req.session.user) res.send("SESSION");
else res.render('users/new_user', {title:"NEW USER"});
});
/*there is more content... but not relevant. */
function makeTheUserSession(result, res)
{
result['go'] = '/users';
//res.session.user = result.result[0];
//res.cookie('user', result.result[0]);
res.send(result);
}
The function makeTheUserSession is call from the method post of '/users' (to find a users on the data base).
If I uncomment the res.session.user line, when I invoque makeTheUserSession the app breaks, stop, capito, dead (Cannot set property 'user' of undefined)...
If I uncomment the res.cookie('user', result... line, when I invke the function, and after I see the browser cookies on the settings I found a cookie called user with the values of result.result[0]... but after on the get method it doesn´t works how I expect... res never sends me "COOKIE".
I had sawn the same question many times repeated, but I didn´t see a answer that worth for me: some ones talk about connect middleware (I am using express), other say to use "app.use(express.session(keyword)) but it only works with the old version of express. The express-session module is deprecated, and I would want to use a more actuallity middleware.
I hope your answers. Thank you very much.
It's req.session not res.session, fix that and you should be good to go.