I use passport.js to authenticate user. I have 2 function there to check whether user is logged in or not.
First function:
isLoggedIn(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
else {
res.redirect('/');
}
}
2nd function:
isLoggedInCheck(req, res) {
if (req.isAuthenticated()) {
return true;
}
else {
return false;
}
}
I take these 2 functions in class called Helper.
When I use the 1st function (I pass it in routes function as middleware) it works:
var Helper = require('../helpers/helper');
var helper = new Helper();
router.get('/', helper.isLoggedIn, admin.melihat_daftar_venue);
But when i want to use second function:
if (helper.isLoggedInCheck) {
//code
}
else{
}
The function just return function definition instead of true/false. How to fix it. Thanks
You are using isLoggedIn as a ExpressJS middleware while isLoggedInCheck inside condition that's why you need to call function( helper.isLoggedInCheck(req, res) inside if condition while define inside get function
if (helper.isLoggedInCheck(req, res)) {
//code
}
else{
}
and first one is
router.get('/', helper.isLoggedIn, admin.melihat_daftar_venue);
or (not recommended, just showing example)
router.get('/', (req, res, next) => {
helper.isLoggedIn(req, res, next)
}, admin.melihat_daftar_venue);
Related
I'm new to javascript, nodejs, and express, and confused of using next().
I want my code to move on to the next router with next(), but it seems to move on to the next then.
My code:
//validation
router.post('/requests', (req, res, next) => {
let {myData} = req.body
basicCheck(res, cluster, myData)
.then(() => {
if (myCheck()) {
next()
return // Doesn't need to do rest of the code. Just move on to the next router.post
}
...
return Promise.all(somePromises)
})
.then(() => {
...
return Promise.all(somePromises)
})
.then(() => {
if (someCheck() {
next()
} else {
res.status(400).send('message') // My code reaches here! even when myCheck() is true
}
})
.catch((err) => {
...
})
})
// where next() needs to be
router.post('/requests', (req, res) => {
...
})
When next() is outside the basicCheck, next() goes to the next router.post.
I don't get the concept of where next() indicates.
How can I correct this code while doing myCheck() inside basicCheck()?
With next() you move to the next middleware.
Exapmle:
You have a route like:
app.get("/", (req, res, next) => {
res.send("hello")
})
Instead of using an anonymous function you can declare an function and use it it like:
function firstMiddleware(req, res, next){
res.send("hello")
}
app.get("/", firstMiddleware);
What you can do is you can have multiple middlewares in your route like:
function firstMiddleware(req, res, next){
console.log("hy");
next()
}
function secondMiddleware(req,res,next) {
console.log("hello")
res.send("hello");
}
app.get("/", firstMiddleware, secondMiddleware);
As you can see. In my first middleware i use next(). This tells express.js to move to the next middleware in this case secondMiddleware
The middlewares gets executed from the left to right and with next() you tell them to move to the next until you are on the end.
Usually the last middleware is your API endpoint and you should not use next() otherwise you would "jump out" of your route and you would receive an error if you have defined an global error handler
Also sidenote: A bonus would be to seperate your routes and logic by creating an file called controller.js for example.
controller.js
function firstMiddleware(req, res, next){
console.log("hy");
next()
}
function secondMiddleware(req,res,next) {
console.log("hello")
res.send("hello");
}
module.exports = {
firstMiddleware,
secondMiddleware
}
Now you can import it:
const { firstMiddleware, secondMiddleware } = require("./controller.js");
app.get("/", firstMiddleware, secondMiddleware);
This makes your code easier to maintain as it grows
EDIT:
router.post("/requests", async (req, res, next) => {
let { myData } = req.body;
let checkresult = await awbasicCheck(res, cluster, myData);
if (myCheck()) {
return next();
}
let someResults = await Promise.all(somePromises);
let someMoreResults = await Promise.all(somePromises);
if (someCheck()) {
return next();
} else {
res.status(400).send("message"); // My code reaches here! even when myCheck() is true
}
});
You use return witch yes stops the function from execution BUT what you also do is an promise chaining.
I have written here an async / await approach
I have a router handler configured in a Restify route. In that handler I make a call to a custom module where I do some error checking. When I hit an error condition, I my code returns next(err). I see the error message in the browser, but for some reason my code continues executing after that as well.
The Restify router handler
HttpHandlers.prototype.callHttp = function(req, res, next) {
myUtils.checkInputRules(req, res, next, handlerConfig.inputRules);
//This code is getting executed:
logger.debug("Updated ...
The function being called:
myUtils.checkInputRules = function checkInputRule(req, res, next, inputRules) {
...
} else {
if (inputRule.ifFalse) {
var evalStr = inputRule.ifFalse;
if (evalStr != null) {
logger.debug("Executing condition.iFalse: "+evalStr);
//The code is itting this location
return next(new Error("Internal Error: Failure."));
...
You didn't include the entire code but the issue may be something like this: When you return from a function, it is important which function you return from. For example:
function handler(req, res, next) {
helper(req, res, next);
// this will still run
}
function helper(req, res, next) {
if (something) return next();
}
Here it seems that you are running the myUtils.checkInputRules function and you are returning from your myUtils.checkInputRules function, but you are not actually returning from HttpHandlers.prototype.callHttp so everything after myUtils.checkInputRules(req, res, next, handlerConfig.inputRules); is still executed.
You didn't show the entire code but it seems all synchronous. In that case you can do something like this:
function handler(req, res, next) {
if (helper(req, res, next)) {
// next() was already called
} else {
// do something else - next() not called yet...
}
}
function helper(req, res, next) {
if (something) {
next();
// indicate that next() was already called:
return true;
}
// possibly do something else
}
I am using Express.js as http server. Defined all my routes.
Most endpoints need to verify session before returning a response. E.g. below code serves users in the system and list of services respectively:
function getUsers(req, res, next) {
verifyUser(req, res, next, function () {
//serve users
});
}
function getServices(req, res, next) {
verifyUser(req, res, next, function () {
//serve services
});
}
You probably noticed there is a verifyUser function which validates the session. Which is as below.
function verifyUser(req, res, next, callback) {
var sessionKey = req.cookies.sessionKey;
var user = users.userBySession(sessionKey);
if (user) {
callback(req, res, next, user);
} else {
res.status(401).send({
message: 'Unauthorized'
});
}
}
As you can see I keep passing in req, res and next parameters along with a callback whenever I use this function.
I tried to use apply function to make it easier. Changed my getUsers function like this:
function getUsers(req, res, next) {
verifyUser
.apply(null, arguments, function () {
//serve users
});
}
The problem with this approach is callback is not passed into verifyUser function. And I don't really like passing null as scope with each call.
How can I achieve this by writing less and better code ? Any ideas?
You could use bind to create a 'partial function':
// create bound responseHelper object
var responseHelper = verifyUser.bind(null, req, res, next);
// usage
responseHelper(getUsersCallback); // same as verifyUser(req, res, next, getusersCallBack);
I think you're looking to turn verifyUser into a middleware function.
function verifyUser (req, res, next) {
var user = // yadda yadda session stuff
if (user) {
req.user = user; // [1] what you do to the req object here...
} else {
return res.status(401).send({ message: "No way Smokey Joe"});
/**
* alternatively, do something like
* var err = new Error("Not authorized");
* err.statusCode = 401;
* return next(err);
*
* this will kick off Express' error handling mechanism,
* which you should read about in the docs (see the link below)
*/
}
next();
// very important to call next after this verifyUser has done its job
// if you don't, the next middleware won't go off,
// and the request will just hang
}
function getUsers (req, res, next) {
// [2] will show up on the req object here, assuming you chain these
// two functions together as middleware
}
app.get("/users", verifyUser, getUsers);
app.get("/services", verifyUser, getServices);
// here's a route that needs no session auth, so no need to verifyUser
app.get("/latest-posts", getLatestPosts);
When you tell Express to use a function or attach a function to a route path via get('/my/route', hanlderFun) or some such, you've basically turned handlerFun into a middleware.
You can define however many middleware as handlers on a route as you like, and they'll all execute in turn as long as you keep calling next.
app.post("/checkout", verifyUser, tallyCart, checkInventory, doPayment, sendInvoice);
The job of next is to pass control from the current middelware to the next one. It's an object
You can do other stuff with next, too, which you should read up on in the docs.
http://expressjs.com/en/guide/writing-middleware.html
http://expressjs.com/en/guide/using-middleware.html
The docs on routing have good info on middleware as well:
http://expressjs.com/en/guide/routing.html
For extra credit, check out error handling middleware, too:
http://expressjs.com/en/guide/error-handling.html
Assume I have a route with the following namespace:
app.use('/logged', adminRoute);
Now, I have created the following passportjs function:
app.get('/logged/panel', function (req, res) {
if (req.user === undefined) {
res.redirect('/login');
} else {
res.render('/logged/panel', {
user: req.user
})
}
});
This function checks wether the user is authenticated on the /logged/panel pattern.
I want to modify this function so it will perform checks on each get/post url pattern from adminRoute. How can I do this correctly?
Consider using express.Router.
function ensureAuthenticated(req, res, next) {
if(logged) return next();
res.redirect('/login');
}
var loggedRouter = express.Router();
loggedRouter
.use(ensureAuthenticated)
.get('/panel', panelHandler)
.get('/other', otherHandler);
var mainRouter = express.Router();
mainRouter.use('/logged', loggedRouter);
app.use(mainRouter);
You can include checking if user is logged inside ensureAuthenticated function. This middleware function will always be executed before /logged/panel and /logged/other.
I am creating an API with NodeJS, Express and PassportJS but I think this is a JavaScript question.
app.get('/test', function (req, res, next) {
passport.authenticate('bearer', { session: false },
function (err, user, info) {
if (user === false) {
res.send('ko');
} else {
res.send('ok');
}
})(req, res, next);
});
My question is:
Why is (req, res, next) after the authenticate function? Is it related with the scope?
Seems that the function password.authenticate returns a function/closure. The code is like
foo(x, y)(z);
i.e. the function returned by the call foo(x, y) is called with parameter z.
A very simple example is
function multiplier(k) {
return function(x) { return x*k; };
}
console.log(multiplier(7)(6)); // outputs 42
The () call the function. The variables inside it are passed to it as arguments. You can see them coming into the containing function on line one of your code.