I'm using a basicAuth middleware in my app, and it works.
But then, in my routes functions, I would like to get the login that was used by the user to authenticate. Assuming req is my request variable, this was supposed to be in req.remoteUser (and later in req.user).
But currently both are set to 'true'. I check that the middleware is used before calling app.use(app.router), so the req request should be populated ! I also use a bodyParser on the line right after basicAuth, and it populates the request correctly.
Nothing much on google, only one issue in express github saying that now it works and both req.user and req.remoteUser have the value.
One needs to provide the username to the callback function (even if the calling code obviously has it in it's context) if we want req.user to be set.
So intead of doing this (as the great tutorial I followed said) :
var express = require('express');
var app = express();
// Authenticator
app.use(express.basicAuth(function(user, pass, callback) {
var result = (user === 'testUser' && pass === 'testPass');
callback(null /* error */, result);
}));
app.get('/home', function(req, res) {
res.send('Hello World');
});
app.listen(process.env.PORT || 8080);
One must change the function into :
app.use(express.basicAuth(function(user, pass, callback) {
if (user === 'testUser' && pass === 'testPass') {
callback(null /* error */, user);
} else {
callback(null, null);
}
}));
And for those wondering, yes that means we can't have a user whose name is the empty String (else it will be interpreted as false by express), which seems a shame.
Related
I have written a code in NodeJS where when i hit the url, i need the server to pass through three middleware functions authentication, cookies, logging. Here it happens , but the console gets printed twice. Can you help me figure out why.
var express = require('express');
var app = express();
var router = require('express').Router();
/* Add the middleware to express app */
app.use (function authentication(req,res,next){
if(req.method === 'GET'){
console.log("Inside Authentication.js")
next(); // If your don't use next(), the mmand won't go to the next function.
}
else{
console.log("Inside else Authentication.js")
}
})
app.use( function cookies(req,res,next){
if (req.method === 'GET'){
console.log("Inside cookies.js")
next();
}
else
{
console.log("Inside else cookies.js")
}
})
app.use( function logging(req,res,next){
if(req.method === 'GET'){
console.log("Inside Logging.js");
next();
}
else{
console.log("Inside else of Logging.js");
}
})
app.use(function(req,res) {
res.send('Hello there !');
});
app.listen(8080);
o/ p -
E:\NodeJSProject\middleware>node app.js
Inside Authentication.js
Inside cookies.js
Inside Logging.js
Inside Authentication.js
Inside cookies.js
Inside Logging.js
Your browser will perform a pre-flight CORS request (i.e. an OPTION request) to see whether you're allow to perform the request.
From your perspective its just one request, but the browser is performing two requests and your express server is executing both requests in full.
Given you're using express there is middleware available to handle those requests specifically.
See here for documentation.
If you want to avoid the CORS request altogether, your website and API need to be served from the same host, port, and protocol.
You can read more about CORS here, or you can search Stack -- theres extensive posts.
I am very new to Node Js and Concept of Callback Mechanism , I have working code to authenticate the User based on the LDAP using ldapjs but I wanted to know the mechanism how its working with respect to data flow and callbacks.
In the below code I have few doubts, Can someone help me clarifying
What does it means with cb(err === null, err, res);
When I do console.log with fake_res it shows as true Why its true?
I see some post referring we need use to error as first callback, Is it so?
And Finally I wanted to understand why is the res used in output and authDN are same
And finally how generally callbacks works in NodeJS
Before asking this question I have gone through many forums but couldn't relate with the below code
Link 1
Link 2
Link 3
Link 4
var express = require('express');
var util = require('util');
CircularJSON = require('circular-json');
var router = express.Router();
var ldap = require('ldapjs');
var bodyParser = require('body-parser');
var userNT;
var password;
var app = express();
function authDN(dn, password, cb, res) {
var client = ldap.createClient({
url: 'ldap://localhost:389'
});
client.bind(dn, password, function(err) {
client.unbind();
cb(err === null, err, res);
});
}
function output(fake_res, err, res) {
if (fake_res) {
console.log('success');
res.status(200).send('{"status":"success"}');
} else {
console.log('failure');
res.status(401).send('{"status":"failure"}');
}
}
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({
extended: true
})); // support encoded bodies
router.post('/login', postData);
function postData(req, res) {
userNT = req.body.ntid;
password = req.body.password;
authDN(userNT, password, output, res);
};
module.exports = router;
Okay let us go try to do it step by step :
Here if you see authDN has third parameter cb this is your callback function. Now to trace it back check the value of argument provided to this function authDN when it is called inside postData function, here cb = function output
Now first param of your output is fake_res which is either true or false, this depends on response of client.bind
If it fails you will get some error hence it will go on to be false. Here comes the answer to your question 2 because your credentials seem to be correct always this err is equal to null thus your fake_res is always true.
Answering question 4 it is because it is passed on as param to send response back to the API call you made using router.post
About number 3 it is just more readable and better to use an error first callback, but not necessary.
I am developing a site using the mean stack and express-jwt to block access to api calls to my site unless a user is authenticated. There are certain api calls that I need users not logged in to access, i.e., /api/login and /api/register. When I access the endpoints using firebug everything seems to work as expected, it blocks under the right conditions and allows under the right conditions. I am even receiving the token under firebug. However, if I test using mocha/chai I am getting "401 unauthorized" error indicating "No authorization token was found". I am using the following code to ignore selected endpoints:
app.js:
let expressJwt = require('express-jwt')
app.use(expressJwt({secret: process.env.AUTH_KEY}).
unless({path: ['/api/login', '/api/register', /^\/api\/external\/.*/]}));
routes.js:
module.exports = function(app, mongoose){
app.use("/api/register", require("./routes/registration")(mongoose));
app.use("/api/external/games", require("./routes/games")(mongoose));
app.use("/api/external/shopping", require("./routes/shopping")(mongoose));
}
routes/registration.js:
'use strict'
module.exports = function(){
const express = require('express');
const router = express.Router();
const RegistrationFactory = require('../factories/RegistrationFactory');
const registrationFactory = new RegistrationFactory();
router.use(function(req, res, next) {
next();
});
/* GET users listing. */
router.post('/', function(req, res, next) {
const registrationService = registrationFactory.create();
registrationService.register(req.body, function(err, user){
if (!err && user){
console.log(err);
res.sendStatus(200);
} else {
return next(err);
}
})
});
return router;
}
I would like to block access to all of the routes except the three listed above. Can someone point out what I am doing wrong because I am not seeing it? I am a newbie to node.js.
I'm using sessions and cookies to authenticate the users. I would like to check for users having a cookie and if so i will set the sessions variables.
So basicly what i do is :
Check if sessions variables exist
If not, check if user has cookie
If he has a cookie, I compare the value in my database.
If everything's ok, I set up the session.
Now i'd like to have that process into a module so i don't have to paste that code into each routes of my site.
Let's say I've put all that code in a middleware route located at routes/middleware/check_auth.js.
How do I export this module so I can check in my route page if the user has auth or not, something like :
//routes/index.js
var check_auth = require('./middleware/check_auth');
module.exports = function(app){
app.get('/', check_auth, function(req, res){
if(variable_from_check_auth == true){
res.render('index_with_auth');
}else{
res.render('index_without_auth');
}
});
};
Btw, I'm not sure if it's the right way to do or if I simply have to :
Call the module on each routes.
Check for some sessions variables before rendering.
If someone could help me!
You can just export your middleware as simple as this(assuming you are using express session handler and cookie parser):
var userModel = require('./user');
module.exports = function check_auth(res, req, next) {
if (!res.session) {
req.send(401);
return;
}
userModel.isAuthenticated(req.session.id, function (result) {
if (!result) {
req.send(401);
return;
});
next();
});
};
I'm trying to do a very simple Basic Auth middleware for Express on Node.js as demonstrated here: http://node-js.ru/3-writing-express-middleware
I have my middleware function:
var basicAuth = function(request, response, next) {
if (request.headers.authorization && request.headers.authorization.search('Basic ') === 0) {
// Get the username and password
var requestHeader = new Buffer(
request.headers.authorization.split(' ')[1], 'base64').toString();
requestHeader = requestHeader.split(":");
var username = requestHeader[0];
var password = requestHeader[1];
// This is an async that queries the database for the correct credentials
authenticateUser(username, password, function(authenticated) {
if (authenticated) {
next();
} else {
response.send('Authentication required', 401);
}
});
} else {
response.send('Authentication required', 401);
}
};
And I have my route:
app.get('/user/', basicAuth, function(request, response) {
response.writeHead(200);
response.end('Okay');
});
If I try to curl this request I get:
curl -X GET http://localhost/user/ --user user:password
Cannot GET /user/
This works totally cool when I add the middleware while calling createServer(), but when I do it per-request like I am in this route, it just dies quietly server-side. Unfortunately, since not all requests require authentication, I can't make this a global middleware.
I've tried flipping off Express and just using Connect and I get the same result, so I assume it's something in there. Has anybody experienced this before?
Edit: I should also mention that I've logged the relevant code exhaustively and next is being called, but it just appears to go nowhere.
Edit 2: For the record, an "empty" middleware also fails silently:
var func = function(request, response, next) {
next();
};
app.get('/user', func, function(request, response) {
response.writeHead(200);
response.end('Okay');
});
This also has the same result.
function(request, response, callback) {
vs
next();
Your supposed to either change callback to next or vica versa.
I found this link.
Express middleware: Basic HTTP Authentication
The author seems to be doing the same thing as you did, except he has a return after the next().