I have two app.listens in the code and I get an error ,when I take one of them out ,the authentication stops working ,how can I resolve the problem ,I'm trying to implement passport js into my app (I have followed a tutorial and I have passport js example working I just want to implement it to myproject )this is the following error I'm getting
screenshot here
'use strict'
const express = require('express')
const fs = require('fs')
const https =require('https')
const path = require('path')
var app = express();
var bodyParser = require('body-parser');
var morgan = require('morgan');
var mongoose = require('mongoose');
var jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens
var config = require('./config'); // get our config file
var Index = require('./api/planner/index'); // get our mongoose model
var port = process.env.PORT || 3443; // used to create, sign, and verify tokens
mongoose.connect(config.database); // connect to database
app.set('superSecret', config.secret); // secret variable
// use body parser so we can get info from POST and/or URL parameters
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// use morgan to log requests to the console
app.use(morgan('dev'));
// =======================
// routes ================
// =======================
// basic route
app.get('/', function(req, res) {
res.send('Hello! The API is at http://localhost:' + port + '/api');
});
// API ROUTES -------------------
// get an instance of the router for api routes
var apiRoutes = express.Router();
// TODO: route to authenticate a user (POST http://localhost:8080/api/authenticate)
apiRoutes.post('/authenticate', function(req, res) {
// find the user
User.findOne({
name: req.body.name
}, function(err, user) {
if (err) throw err;
if (!user) {
res.json({ success: false, message: 'Authentication failed. User not found.' });
} else if (user) {
// check if password matches
if (user.password != req.body.password) {
res.json({ success: false, message: 'Authentication failed. Wrong password.' });
} else {
// if user is found and password is right
// create a token
var token = jwt.sign(user, app.get('superSecret'), {
expiresIn: 1440 // expires in 24 hours
});
// return the information including token as JSON
res.json({
success: true,
message: 'Enjoy your token!',
token: token
});
}
}
});
});
// TODO: route middleware to verify a token
apiRoutes.use(function(req, res, next) {
// check header or url parameters or post parameters for token
var token = req.body.token || req.query.token || req.headers['x-access-token'];
// decode token
if (token) {
// verifies secret and checks exp
jwt.verify(token, app.get('superSecret'), function(err, decoded) {
if (err) {
return res.json({ success: false, message: 'Failed to authenticate token.' });
} else {
// if everything is good, save to request for use in other routes
req.decoded = decoded;
next();
}
});
} else {
// if there is no token
// return an error
return res.status(403).send({
success: false,
message: 'No token provided.'
});
}
});
// route to show a random message (GET http://localhost:8080/api/)
apiRoutes.get('/', function(req, res) {
res.json({ message: 'Welcome to the coolest API on earth!' });
});
// route to return all users (GET http://localhost:8080/api/users)
apiRoutes.get('/users', function(req, res) {
User.find({}, function(err, users) {
res.json(users);
});
});
// apply the routes to our application with the prefix /api
app.use('/api', apiRoutes);
// we'll get to these in a second
app.get('/setup', function(req, res) {
// create a sample user
var nick = new User({
name: 'Nick Cerminara',
password: 'password',
admin: true
});
// save the sample user
nick.save(function(err) {
if (err) throw err;
console.log('User saved successfully');
res.json({ success: true });
});
});
// =======================
// start the server ======
// =======================
app.listen(port);
console.log('Magic happens at http://localhost:' + port);
const directoryToServe = 'client'
//const port = 3443
app.use('/',express.static(path.join(__dirname,'..',directoryToServe)))
const httpsOptions = {
cert: fs.readFileSync(path.join(__dirname,'ssl','server.crt')),
key: fs.readFileSync(path.join(__dirname,'ssl','server.key'))
}
https.createServer(httpsOptions, app)
.listen(port, function()
{
console.log(`Serving the ${directoryToServe}/directory at https://localhost:${port}`)})
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app
app.get('/', function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.end("We're up and running!!!");
});
var plan = require('./api/planner/index');
app.get('/api/planner',plan.index);
app.post('/api/planner',plan.create);
app.put('/api/planner/:id',plan.update);
app.delete('/api/planner/:id',plan.delete);
console.log("Server running at http://127.0.0.1:8000/");
//
This err is probably caused by using a busy port. If you are using ubuntu, you can check the status of ports by lsof -i:portnumber. After running the command you will have a PID.
You can release the port by kill -9 pid.
Windows and mac have similar commands.
Related
I am trying to implement an authentication system for the express REST API.
I got this code for using jsonwebtoken from a tutorial.
when i run the app in local it works fine, i can log in and out but it doesn't when i deployed it on HERUKU, app.get('/', (req, res) returns Invalid user to access it.
server.js
require('dotenv').config();
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');
const utils = require('./utils');
const userData =require('./data.json')
const app = express();
const port = process.env.PORT || 4000;
// enable CORS
app.use(cors());
// parse application/json
app.use(bodyParser.json());
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
//middleware that checks if JWT token exists and verifies it if it does exist.
//In all future routes, this helps to know if the request is authenticated or not.
app.use(function (req, res, next) {
// check header or url parameters or post parameters for token
let token = req.headers['Authorization'];
if (!token) return next(); //if no token, continue
token = token.replace('Bearer ', '');
jwt.verify(token, process.env.JWT_SECRET, function (err, user) {
if (err) {
return res.status(401).json({
error: true,
message: "Invalid user."
});
} else {
req.user = user; //set the user to req so other routes can use it
next();
}
});
});
// request handlers
app.get('/', (req, res) => {
if (!req.user) return res.status(401).json({ success: false, message: 'Invalid user to access it.' });
res.send('Welcome to netperf Analytics back! - ' + req.user.name);
});
// validate the user credentials
app.post('/users/signin', function (req, res) {
const user = req.body.username;
const pwd = req.body.password;
// return 400 status if username/password is not exist
if (!user || !pwd) {
return res.status(400).json({
error: true,
message: "Username or Password required."
});
}
// return 401 status if the credential is not match.
if (user !== userData.username || pwd !== userData.password) {
return res.status(401).json({
error: true,
message: "Username or Password is Wrong."
});
}
// generate token
const token = utils.generateToken(userData);
// get basic user details
const userObj = utils.getCleanUser(userData);
// return the token along with user details
return res.json({ user: userObj, token });
});
// verify the token and return it if it's valid
app.get('/verifyToken', function (req, res) {
// check header or url parameters or post parameters for token
var token = req.body.token || req.query.token;
if (!token) {
return res.status(400).json({
error: true,
message: "Token is required."
});
}
// check token that was passed by decoding token using secret
jwt.verify(token, process.env.JWT_SECRET, function (err, user) {
if (err) return res.status(401).json({
error: true,
message: "Invalid token."
});
// return 401 status if the userId does not match.
if (user.userId !== userData.userId) {
return res.status(401).json({
error: true,
message: "Invalid user."
});
}
// get basic user details
var userObj = utils.getCleanUser(userData);
return res.json({ user: userObj, token });
});
});
app.listen(port, () => {
console.log('Server started on: ' + port);
});
utils.js
// generate token using secret from process.env.JWT_SECRET
var jwt = require('jsonwebtoken');
// generate token and return it
function generateToken(user) {
//1. Don't use password and other sensitive fields
//2. Use the information that are useful in other parts
if (!user) return null;
var u = {
userId: user.userId,
name: user.name,
username: user.username,
isAdmin: user.isAdmin
};
return jwt.sign(u, process.env.JWT_SECRET, {
expiresIn: 60 * 60 * 24 // expires in 24 hours
});
}
// return basic user details
function getCleanUser(user) {
if (!user) return null;
return {
userId: user.userId,
name: user.name,
username: user.username,
isAdmin: user.isAdmin
};
}
module.exports = {
generateToken,
getCleanUser
}
error
I am learning NodeJS, and I am having trouble understanding why my middleware is always executed.
From my understanding, the middleware as I wrote it should be executed for all the routes declared after the middleware itself.
My index.js is something like this:
const express = require('express');
const mongoose = require('mongoose');
const router = express.Router();
const bodyParser = require('body-parser'); // Parse incoming request bodies in a middleware before your handlers, available under the req.body property.
const configdb = require('./config/db_develop');
const path = require('path');
const authentication = require('./routes/authentication')(router); // Import Authentication Routes
const noNeedForAuth = require('./routes/noNeedForAuth')(router);
const app = express();
const port = 30000;
mongoose.Promise = global.Promise;
mongoose.connect(configdb.uri, (err) => {
if (err) {
console.log('Could not connect to database ' + err);
} else {
console.log('Connected to the database ' + configdb.db);
}
});
app.use(bodyParser.urlencoded({
extended: false
})); // parse application/x-www-form-urlencoded
app.use(bodyParser.json()); // parse application/json
app.use(express.static(__dirname + '/frontend/buildpath'));
app.use('/noNeedForAuth', noNeedForAuth);
app.use('/users', authentication);
app.get('*', (req, res) => {
res.send(path.join(__dirname + '/client/dist'));
});
app.listen(port, () => {
console.log('Listening on port ' + port + '!');
});
The authentication.js is:
const User = require('../models/user'); // Import User Model Schema
const config = require('../config/db_develop.js'); // Import database configuration
const jwt = require('jsonwebtoken'); // Compact, URL-safe means of representing claims to be transferred between two parties.
module.exports = (router) => {
router.post('/register', (req, res) => {
//Register
});
router.post('/login', (req, res) => {
//Login
});
// MIDDLEWARE
router.use((req, res, next) => {
const token = req.headers['authorization']; // Create token found in headers
// Check if token was found in headers
if (!token) {
res.status(403);
res.json({
success: false,
message: 'No token provided'
}); // Return error
} else {
// Verify the token is valid
jwt.verify(token, config.secret, (err, decoded) => {
// Check if error is expired or invalid
if (err) {
res.json({
success: false,
message: 'Token invalid: ' + err
}); // Return error for token validation
} else {
req.decoded = decoded; // Create global variable to use in any request beyond
next(); // Exit middleware
}
});
}
});
/* ===============================================================
Route to get user's profile data
=============================================================== */
router.get('/profile', (req, res) => {
//Profile, protected route
});
return router; // Return router object to main index.js
}
And my noNeedForAuth.js is
module.exports = (router) => {
/* ===============================================================
Route to get all sections' names
=============================================================== */
router.get('/something', (req, res) => {
// Do something
res.json({
message: 'foobar'
});
});
return router; // Return router object to main index.js
}
From my understanding, a query to /noNeedForAuth/something should be executed without passing from the middleware, so without the need for Authentication. But this is not happening, the middleware is executed first, always.
What am I missing?
Thanks
You are applying your middleware without any mount path to your router. It will execute for any route.
Try something like:
// MIDDLEWARE
router.use('/protected', (req, res, next) => {
const token = req.headers['authorization']; // Create token found in headers
// Check if token was found in headers
if (!token) {
res.status(403);
res.json({
success: false,
message: 'No token provided'
}); // Return error
} else {
// Verify the token is valid
jwt.verify(token, config.secret, (err, decoded) => {
// Check if error is expired or invalid
if (err) {
res.json({
success: false,
message: 'Token invalid: ' + err
}); // Return error for token validation
} else {
req.decoded = decoded; // Create global variable to use in any request beyond
next(); // Exit middleware
}
});
}
});
All your routes, where the user have to be authenticated, are behind /protected.
I'm a little back end developer for the node js. Currently, I'm creating an application to increase my skill level with node js. So I thought i'd try to learn JSON webtoken(jwt) for the user authentication part. I am using this link to get an idea of how it works. But now I have a problem that I must change and then fix that differs from the tutorial. The middleware that the tutorial gives you is not working for the secured routes. So let me describe what happens when my code runs. If we didn't provide any token to any route that the middleware checks then the router works as we expect it to without returning any errors from the middleware. So please let me know a solution to fix this in the easiest possible way. Thank you.
secured routes file for api
//Node js libraries
const express = require('express');
const router = express.Router();
const app = express();
const jwt = require('jsonwebtoken');
//Static files
const Users = require('../models/users');
app.set('superSecret', 'thisissecretkeyforapi');
//Routes here
router.post('/', function(req, res){
if(req.body.username == '' || req.body.password == '') {
res.send('Fields must be required');
}
else {
Users
.findOne({
username: req.body.username
},
function(err, user){
if(!user){
res.send('No user found');
}
else {
if(user.password != req.body.password) {
res.send('Wrong password');
}
else {
var token = jwt.sign(user, app.get('superSecret'), {
expiresIn: 60*15
});
res.send({
message: "Token here",
token: token
})
}
}
});
}
})
router.get('/profile', function(req, res){
console.log(req.decoded);
res.send('profile here');
});
module.exports = router;
app.js file for all middlewares
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var morgan = require('morgan');
var mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://cordy:lolla123#ds042459.mlab.com:42459/musiclk', {
useMongoClient: true
});
app.set("view engine", "ejs");
app.set('superSecret', 'thisissecretkeyforapi');
app.use(morgan('dev'));
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
require('./controllers/index')(app);
app.set('superSecret', 'thisissecretkeyforapi');
admin_routes = require('./controllers/admin_routes');
admin_routes.use(function(req, res, next) {
// check header or url parameters or post parameters for token
var token = req.body.token || req.query.token || req.headers['x-access-token'];
// decode token
if (token) {
// verifies secret and checks exp
jwt.verify(token, app.get('superSecret'), function(err, decoded) {
if (err) {
return res.json({
success: false,
message: 'Failed to authenticate token. The token is expired' });
}
else {
// if everything is good, save to request for use in other routes
req.decoded = decoded;
next();
}
});
} else {
// if there is no to
// return an error
return res.status(403).send({
success: false,
message: 'No token provided.'
});
}
});
app.use('/admin', admin_routes);
app.listen(process.env.PORT || 1337, function(){
console.log("Now listening for the requests");
});
There is all of my code.
i am new to nodejs and trying to implement a router. I have written router in a separate file, say apiRoutes.js ass shown below
var express = require('express');
// API ROUTES -------------------
// get an instance of the router for api routes
var apiRoutes = express.Router();
var User = require('./app/models/user');
var jwt = require('jsonwebtoken');
// TODO: route to authenticate a user (POST http://localhost:8080/api/authenticate)
// TODO: route middleware to verify a token
// route to show a random message (GET http://localhost:8080/api/)
apiRoutes.get('/', function(req, res) {
res.json({ message: 'Welcome to the coolest API on earth!' });
});
// route to return all users (GET http://localhost:8080/api/users)
apiRoutes.get('/users', function(req, res) {
User.find({}, function(err, users) {
res.json(users);
});
});
// route to authenticate a user (POST http://localhost:8080/api/authenticate)
apiRoutes.post('/authenticate', function(req, res) {
// find the user
User.findOne({
name: req.body.name
}, function(err, user) {
if (err) throw err;
if (!user) {
res.json({ success: false, message: 'Authentication failed. User not found.' });
} else if (user) {
// check if password matches
if (user.password != req.body.password) {
res.json({ success: false, message: 'Authentication failed. Wrong password.' });
} else {
// if user is found and password is right
// create a token
var token = jwt.sign(user, app.get('superSecret'), {
expiresInMinutes: 1440 // expires in 24 hours
});
// return the information including token as JSON
res.json({
success: true,
message: 'Enjoy your token!',
token: token
});
}
}
});
});
module.export = apiRoutes;
and in another file, say server.js
// =======================
// get the packages we need ============
// =======================
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var morgan = require('morgan');
var mongoose = require('mongoose');
var jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens
var config = require('./config'); // get our config file
var User = require('./app/models/user'); // get our mongoose model
var apiRoutes = require('./apiRoutes');
// =======================
// configuration =========
// =======================
var port = process.env.PORT || 8080; // used to create, sign, and verify tokens
mongoose.connect(config.database); // connect to database
app.set('superSecret', config.secret); // secret variable
// use body parser so we can get info from POST and/or URL parameters
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// use morgan to log requests to the console
app.use(morgan('dev'));
// =======================
// routes ================
// =======================
// basic route
app.get('/', function(req, res) {
res.send('Hello! The API is at http://localhost:' + port + '/api');
});
// API ROUTES -------------------
// we'll get to these in a second
// =======================
// start the server ======
// =======================
app.listen(port);
console.log('Magic happens at http://localhost:' + port);
app.get('/setup', function(req, res) {
// create a sample user
var nick = new User({
name: 'Nick Cerminara',
password: 'password',
admin: true
});
// save the sample user
nick.save(function(err) {
if (err) throw err;
console.log('User saved successfully');
res.json({ success: true });
});
});
// apply the routes to our application with the prefix /api
app.use('/api', apiRoutes);
app.get('/setup', function(req, res) {
// create a sample user
var nick = new User({
name: 'Nick Cerminara',
password: 'password',
admin: true
});
// save the sample user
nick.save(function(err) {
if (err) throw err;
console.log('User saved successfully');
res.json({ success: true });
});
});
And i gets an error as:
TypeError: Router.use() requires middleware function but got a Object
at Function.use (/home/user/jsApp/node_modules/express/lib/router/index.js:458:13)
at EventEmitter.<anonymous> (/home/user/jsApp/node_modules/express/lib/application.js:219:21)
at Array.forEach (native)
at EventEmitter.use (/home/user/jsApp/node_modules/express/lib/application.js:216:7)
at Object.<anonymous> (/home/rawdata/jsApp/server.js:69:5)
at Module._compile (module.js:399:26)
at Object.Module._extensions..js (module.js:406:10)
at Module.load (module.js:345:32)
at Function.Module._load (module.js:302:12)
at Function.Module.runMain (module.js:431:10)
at startup (node.js:141:18)
at node.js:977:3
I thought adding
module.export = apiRoutes;
in apiRoutes.js will solve this problem. But it doesn't. So how should i do this?
I am using this tutorial
https://scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens
to learn about node with restful authentication. I am getting 404s in the route when I post at this
http://localhost:8090/api/authenticate
Here is the response that I get
Cannot POST /api/authenticate
and the console shows 404
POST /api/authenticate 404 2.465 ms - 30
here is my code
// =======================
// get the packages we need ============
// =======================
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var morgan = require('morgan');
var mongoose = require('mongoose');
var jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens
var config = require('./config'); // get our config file
var User = require('./app/models/user'); // get our mongoose model
// =======================
// configuration =========
// =======================
var port = process.env.PORT || 8090; // used to create, sign, and verify tokens
mongoose.connect(config.database); // connect to database
app.set('superSecret', config.secret); // secret variable
// use body parser so we can get info from POST and/or URL parameters
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// use morgan to log requests to the console
app.use(morgan('dev'));
// =======================
// routes ================
// =======================
// basic route
app.get('/', function(req, res) {
res.send('Hello! The API is at http://localhost:' + port + '/api');
});
app.get('/setup', function(req, res) {
// create a sample user
var nick = new User({
name: 'Nick Cerminara',
password: 'password',
admin: true
});
// save the sample user
nick.save(function(err) {
if (err) throw err;
console.log('User saved successfully');
res.json({ success: true });
});
});
// API ROUTES -------------------
// get an instance of the router for api routes
var apiRoutes = express.Router();
// route to authenticate a user (POST http://localhost:8090/api/authenticate)
apiRoutes.post('/authenticate', function(req, res) {
console.log(req);
// find the user
User.findOne({
name: req.body.name
}, function(err, user) {
if (err) throw err;
if (!user) {
res.json({ success: false, message: 'Authentication failed. User not found.' });
} else if (user) {
// check if password matches
if (user.password != req.body.password) {
res.json({ success: false, message: 'Authentication failed. Wrong password.' });
} else {
// if user is found and password is right
// create a token
var token = jwt.sign(user, app.get('superSecret'), {
expiresInMinutes: 1440 // expires in 24 hours
});
// return the information including token as JSON
res.json({
success: true,
message: 'Enjoy your token!',
token: token
});
}
}
});
});
// =======================
// start the server ======
// =======================
app.listen(port);
console.log('Magic happens at http://localhost:' + port);
what am I doing wrong? the / and /setup works just fine
You need to actually use the apiRoutes like this
....
....
app.use('/api', apiRoutes);
// =======================
// start the server ======
// =======================
app.listen(port);
console.log('Magic happens at http://localhost:' + port);
You forgot to route to apiRoutes. Add app.use('/api', apiRoutes);