Another express.js req.session not storing data - javascript

I have been staring at the same SO questions/answers for too long.
I am trying to set my user ID in a req.session variable
here is my app.js stack
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, cors = require('cors')
, mongoose = require('mongoose')
, User = require('./user-model')
, path = require('path')
, mysql = require('mysql');
app = express()
/**
* Middleware.
*/
app.use(cors());
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: 'supercalafragalistic' }));
app.locals.pretty = true;
app.use(express.static(path.join(__dirname, 'public')));
app.set('view engine', 'jade');
...
app.get('/someRoute', routes.someRoute)
I have moved the app.router from top to bottom. Currently it is implied (I just deleted it as I stripped my code looking for error). I have exported app, included app in routes (also erased) . I added middleware. I am lost.....
here is my route stack
//routes/index.js
//requires
var User = require('../user-model')
,qs = require('querystring')
,http = require('http')
,mysql = require('mysql')
,connection = mysql.createConnection({
edited
});
/**
* Set up application.
*/
connection.connect(function(err){
if(err) console.log('failed to connect to mysql because'+ err);
else console.log('connected to mysql');
})
I save the id in the login route:
//login processing route
exports.logIn = function(req, res, next){
console.log('log in request from '+req.body.name);
User.findOne({name:req.body.name}, function(err, user, next){
if(err) return next(err);
if(!user) return res.end();
//check password
user.comparePassword(req.body.password, function(err, isMatch){
if(err) res.send('failed to find user');
console.log(""+isMatch);
if(isMatch){
console.log(user._id.toString()+' user loggd in');
//set session cookie
req.session.loggedIn = user._id.toString();
console.log('req.session.loggedIn set to :'+req.session.loggedIn );
res.send(user);
}else {
res.send('User not found try again');
}
});
});
However, in all other routes the variable is undefined:
// clock status
exports.clockStatus = function(req, res, next){
var user = req.session.loggedIn;
console.log('Status route, userID: '+user);
if(user){
I found the answer in "Cannot access req.session variables in Express/NodeJS" but the last part trails off:
In your case, you have assigned req.session.user = user; only in
/login request. It will not be available for further requests(/auth).
You have to get user information in /auth request too by session id.
(Or) Better you can use passport for authentication.
HOW? How do you "get user information in /auth request too by session id"?
Please ask for anything else you need to straighten me out.
I'm stumped. I have tried some dumb stuff already!

The variable is undefined in other routes if you don't log in first in the browser. Here is my test code:
var express = require('express');
var cors = require('cors');
app = express();
app.use(cors());
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: 'this is a test' }));
app.use(express.static(require('path').join(__dirname, 'public')));
app.get('/login', function(req, res) {
req.session.uid = 'user001';
res.send(req.session);
});
app.get('*', function(req, res) {
res.send(req.session);
});
app.listen(8080);
First visit http://localhost/login in the browser. Then visit other URLs(e.g., http://localhost/test) in this browser, the user id in the session is returned. So maybe there is something wrong in other parts of your code.
Test settings:
Ubuntu Desktop 13.10, 64 bit
Node 0.10.26
NPM 1.4.4
Express 3.4.8
cors 2.2.0

Related

Cannot GET /chatroom

I am new here.
I am trying to develop a web application and I have hit a brick wall which I've been stuck on for a while now.
When running my app.js file all pages show up except for the chatroom. Could someone please take a look at the code and help me out?
I haven't included my code for register and login etc. as they are working fine. When using their router.get and .post concepts for the chatroom I just receive a "Cannot GET /chatroom" message.
Chatroom.js:
const express = require('express');
const router = express.Router();
const socketClient = require('socket.io').listen(4000).sockets;
//Chatroom page: Credit - Traversy Media - https://www.youtube.com/watch?v=hrRue5Rt6Is&t=1542s
router.get('/chatroom', (req, res) => res.render('chatroom.ejs'));
router.post('/chatroom', (req, res) => {
// Connect to Socket.io
socketClient.on('connection', function (socket) {
let chat = db.collection('UsersDB/chats');
// Create function to send status
sendStatus = function (s) {
useUnifiedTopology: true,
socket.emit('status', s);
}
// Get chats from mongo collection
chat.find().limit(100).sort({ _id: 1 }).toArray(function (err, res) {
if (err) {
throw err;
}
// Emit the messages
socket.emit('output', res);
});
// Handle input events
socket.on('input', function (data) {
let name = data.name;
let message = data.message;
// Check for name and message
if (name == '' || message == '') {
// Send error status
sendStatus('Please enter a name and message');
} else {
// Insert message
chat.insert({ name: name, message: message }, function () {
socketClient.emit('output', [data]);
// Send status object
sendStatus({
message: 'Message sent',
clear: true
});
});
}
});
// Handle clear
socket.on('clear', function (data) {
// Remove all chats from collection
chat.remove({}, function () {
// Emit cleared
socket.emit('cleared');
});
});
});
});
app.js:
const express = require('express');
const expressLayouts = require('express-ejs-layouts');
const mongoose = require('mongoose');
const passport = require('passport');
const flash = require('connect-flash');
const session = require('express-session');
const app = express();
// Passport Config
require('./config/passport')(passport);
// DB Config
const db = require('./config/keys').mongoURI;
// Connect to MongoDB
mongoose
.connect(
db,
{ useNewUrlParser: true }
)
.then(() => console.log('MongoDB Connected'))
.catch(err => console.log(err));
// EJS
app.use(expressLayouts);
app.set('view engine', 'ejs');
// Express body parser
app.use(express.urlencoded({ extended: true }));
// Express session
app.use(
session({
secret: 'secret',
resave: true,
saveUninitialized: true
})
);
// Passport middleware
app.use(passport.initialize());
app.use(passport.session());
// Connect flash
app.use(flash());
// Global variables
app.use(function(req, res, next) {
res.locals.success_msg = req.flash('success_msg');
res.locals.error_msg = req.flash('error_msg');
res.locals.error = req.flash('error');
next();
});
// Routes
app.use('/', require('./routes/index.js'));
app.use('/users', require('./routes/users.js'));
app.use('/chatroom', require('./routes/chatroom.js'));
const PORT = process.env.PORT || 5000;
app.listen(PORT, console.log(`Server started on port ${PORT}`));
First and foremost I'd like to thank Cranky Coder; Prakher Londe; and Sunil Lulla for your replies.
I ended up figuring out how to make the chatroom show up. As mentioned before my other pages(login and register etc.) were showing up fine. Unlike the chatroom I had the backend for these in a users.js file. So what I decided to do was move my chatroom.js code into my users.js which was then called in the app.js(the file I run) with app.use('/users', require('.routes/users.js')).
I then changed my router.get code to:
router.get('/chatroom', (req, res) => res.render('chatroom', {
user: req.user
}));
Then in my router.post (see OP for context) I added a res.redirect('/users/chatroom'); before closing with the final bracket.
Lastly I of course edited my .ejs file to have
I found that doing it this way is even better because the chatroom cannot be accessed unless one is logged in.
Thank you again for all your replies and although this is a bit of a specific problem I do hope this helps someone in the future.

Node JS - "Could not get any response" On Insert Data to Database

I'm trying to Insert some data to my database(mysql) with nodejs and I already did make some code but in postman it displays Could not get any response even though I know that I followed properly some tutorials that I watched.
Here's my code
SendOrder.js (models)
var db=require('../dbconnection');
var Task = {
addTask:function(Task,callback){
return db.query("Insert into orders ( order_id, order_no, tbl_id, menu_id, \
order_quantity, order_discount, order_type, \
order_amount, menu_name, menu_price ) values(?,?,?,?,?,?,?,?,?,?)",
[
Task.order_id, Task.order_no, Task.tbl_id, Task.menu_id,
Task.order_quantity, Task.order_discount, Task.order_type,
Task.order_amount, Task.menu_name, Task.menu_price
], callback);
},
}
module.exports=Task;
SendOrder.js (router)
var express = require('express');
var router = express.Router();
var Task = require('../models/SendOrder');
router.post('Send/', function(req, res, next){
Task.addTask(req.body,function(err,count){
console.log(req.body);
if(err)
{
res.json(err);
}
else{
res.json(req.body);
}
});
});
module.exports = router;
EDIT:
dbconnection.js
var mysql=require('mysql');
var connection=mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'opob',
});
module.exports=connection;
app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var mysql = require('mysql');
var connection = require('express-myconnection')
var SendOrder = require('./routes/SendOrder'); // SendOrder
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/SendOrder', SendOrder); // SendOrder
// 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;
Go to Setting in Postman
Off the SSL certificate verification in General tab: (Second option under Request)
Off the Global Proxy Configuration and Use System Proxy in Proxy tab:
If both not work, try below code:
if(err)
{
return res.status(500).json(err);
}
else{
return res.status(200).json(req.body);
}
Hope, this may help you!
=========== EDITED ==============
Looking at your app.js file. It seems you need to use body-parser package to parse the JSON data from request.
npm install body-parser --save
body-parser extract the entire body portion of an incoming request stream and exposes it on req.body.
From whatever you have shared here are the following possibilities:
Your IP/PORT that you are trying to hit is wrong. Please cross verify them again.
The IP that you are trying to hit is not accessible from the machine where postman is installed (I added this possibility as you are using IP instead of localhost)
The third possibility would be server crashing when you hit the Send/ API. If the problem is with your code, most probably this is the reason. In this case, you can check the server console to find crash logs and stack-trace.
As #Hardik has mentioned in the comments is not a wrong URL as that would return 404.

Pass JWT in Header

I am learning JWT with NodeJs. I am stuck at passing the JWT in header actually i do not know how to do this.
index.js file
var express = require('express'),
app = express(),
routes = require('./routes'),
bodyParser = require('body-parser'),
path = require('path'),
ejs = require('ejs'),
jwt = require('jsonwebtoken');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.post('/home',routes.loginUser);
app.get('/', function(req, res) {
res.render('index');
});
app.get('/home',function(req, res) {
jwt.verify(req.token, 'qwertyu6456asdfghj', function(err, data) {
if (err) {
res.sendStatus(403);
}
});
});
app.listen(3000,function(){
console.log("Server running at Port 3000");
});
routes/index.js file
var jwt = require('jsonwebtoken');
exports.home = function(req, res){
res.render('home',{error: false});
};
exports.loginUser = function(req, res) {
var uname = req.body.Username;
var pwd = req.body.Password;
if(uname && pwd === 'admin'){
res.render('home');
var token = jwt.sign({ user: uname }, 'qwertyuiopasdfghj');
console.log('Authentication is done successfully.....');
console.log(token);
}
response.json({
authsuccess: true,
description: 'Sending the Access Token',
token: token
});
};
when i run the application i am getting the token in console.log but
How can I pass token in header and store it in localStorage of browser?
So you want to send the token to frontend but not in the body.
The Recommended way to do so is to use cookies. You can set the token in the cookie and it can be automatically accessed in front-end and in the backend.
res.cookie('tokenKey', 'ajsbjabcjcTOKENajbdcjabdcjdc');
Using authorization headers is also a good approach, but again, in front-end, you have to fetch the token from headers and then save in localStorage or cookie, which you don't have to do in case of cookie.
res.header(field [, value]);
As #ChicoDelaBarrio told you, it depends on the client. Postman is a good place to start checking your backend. But after you have your server working, you have to start working in your client side.
If you want a complete backend example about JWT in Node.js, with Refresh token included, I recomend you this post about it: Refresh token with JWT authentication in Node.js
Probably you can reuse most of the code. In this case the header is not created with BEARER, but with JWT at the beginning, but it works the same

NodeJS JWT token verification

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)

Node.js public css files 404 not found

I'm learning node.js and I have an error serving public CSS files to one URL.
It works with almost every pages, I go on the page and the css file is loaded from 127.0.0.1/css/style.css.
When the URL is 127.0.0.1/project/idProject it tries to get the css file from 127.0.0.1/project/css/style.css.
// INCLUDE MODULES =======================================================
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
var Twig = require('twig');
var twig = Twig.twig;
var path = require('path');
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');
var configDB = require('./config/database.js');
// Assets ================================================================
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.favicon(path.join(__dirname, 'public/images/favicon.ico')));
// Start mongoose
mongoose.connect(configDB.url);
// USER MANAGEMENT =======================================================
require('./config/passport')(passport); // pass passport for configuration
app.use(express.logger('dev')); // log every request to the console
app.use(express.cookieParser()); // read cookies (needed for auth)
app.use(express.json()); // to support JSON-encoded bodies
app.use(express.urlencoded()); // to support URL-encoded bodies
app.set('view engine', 'twig'); // set up twig for templating
app.use(express.session({ secret: 'ilovescotchscotchyscotchscotch' })); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash())
// ROUTES =======================================================
// Set authentication variable
app.use(function (req, res, next) {
app.locals.login = req.isAuthenticated();
next();
});
require('./app/routes.js')(app, passport);
//ERROR MANAGEMENT =======================================================
app.use(app.router);
app.use(function(req, res, next){
res.status(404);
// respond with html page
if (req.accepts('html')) {
res.render('errors/404.twig', { url: req.url });
return;
}
// respond with json
if (req.accepts('json')) {
res.send({ error: 'Not found' });
return;
}
// default to plain-text. send()
res.type('txt').send('Not found');
});
/*app.use(function(err, req, res, next){
// we may use properties of the error object
// here and next(err) appropriately, or if
// we possibly recovered from the error, simply next().
res.status(err.status || 500);
res.render('errors/500.twig', { error: err });
});*/
//SOCKET IO =======================================================
//Quand on client se connecte, on le note dans la console
io.sockets.on('connection', function (socket) {
console.log("New connection");
});
// LISTEN SERVER =======================================================
server.listen(80);
Any idea on how to solve this ?
Regards !
I tried approach which I saw in the comments, and because it did not work for me, I am posting an answer that worked.
All .css files are static, so you have to serve them to the client. However, you do not serve static files as a express middleware. Therefor you have to add them.
app.use(express.static(__dirname, 'css'));
Hi it was a problem for me to solve this, but with the help of salvador it was posible.
The only thing that im going to put is all the code and the you make the reference in the html, you only need to put the file not the folder in the html file.
//The index.js code
var express = require('express');
const path = require ('path');
//app va a ser mi servidor.
var app = express();
app.set('port', 3000)
//app.use(express.static('./public'));
//app.use(express.static( 'css'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'css')));
app.listen(app.get('port'), () => {
console.log('localhost:3000')
} );
this is the structure

Categories

Resources