It's possible show in error middleware what permissions are needed?
//User don't have this permission
app.post("/", guard.check(permissions.$("admin")), (req, res) => {
return new Area(req.body)
.save()
.then(area => {
///....
})
.catch(err => next(err))
})
Error middleware
I would like to show permission here in a console.log()
app.use(function (err, req, res, next) {
if (err.code === "invalid_token") {
return res.status(401).send("...")
}
if (err.code === "credentials_required") {
return res.status(401).send("...")
}
//...
})
You can wrap guard.check middleware into another middleware, and you can put the required permissions to req object, and then you can get it in the error handler middleware.
const customGuard = (permissions) => { // middleware factory
return (req, res, next) => { // return a middleware function
req.requiredPermissions = permissions; // store `permissions` in `req.requiredPermissions`
guard.check(permissions)(req, res, next); // check your permissions with express-jwt-permissions's guard
}
}
Usage, replace
app.post("/", guard.check(permissions.$("admin"))
...
by
app.post("/", customGuard(permissions.$("admin"))
...
Then, in your Error middleware
app.use(function (err, req, res, next) {
console.log("Required permissions: ", req.requiredPermissions); // here
if (err.code === "invalid_token") {
return res.status(401).send("...")
}
if (err.code === "credentials_required") {
return res.status(401).send("...")
}
//...
})
Related
I'm writing a function to create errors and I want to use express' next() function. I have seen working examples using a nested function but my code isn't reached. This is what I have:
/middleware.js
import { errorCreator } from './helper.js';
const middleWare = async (req, res, next) => {
if (!req.headers.header) {
errorCreator('Not Authorized', 401);
}
// More async code here
};
and
/helpers.js
export const errorCreator = (message, statusCode) => {
// this is reached <-----------------
return (req, res, next) => {
// this is not reached <---------------
const error = new Error(message);
error.status = statusCode;
throw error;
};
};
Why do I not reach the nested function?
I have an express route in which I send a header from the front end, in this route I'm making a GET request using axios. I created an interceptor with axios, but I would like to be able to read the req object from the activated route in order to add the header to the axios GET call.
// Example Interceptor
axios.interceptors.request.use(
config => {
// How to get req.headers from the route here?
return config;
},
error => {
return Promise.reject(error);
}
);
// Exemple GET route
router.get('/get', async (req, res, next) => {
try {
const { data } = await axios.get('https://kjhf.fsadjhfewq.....');
} catch (error) {
console.log(error)
}
res.status(200).json({});
});
Is it possible to do this?
So I think the way to do this is to use a middleware to set the headers, and pass on the axios instance
// apiSetHeader.js middleware
exports.default = (req, res, next) => {
req.CustomAxios = axios.create({
headers: { 'HeaderForTheApi': req.headers.apiHeader'}
})
next()
}
And then use that in your route
// Exemple GET route
router.get('/get', apiSetHeaderMiddleware, async (req, res, next) => {
try {
const { data } = await req.CustomAxios.get('https://kjhf.fsadjhfewq.....');
} catch (error) {
console.log(error)
}
res.status(200).json({});
});
Hope this helps!
If I pass passport.authenticate("local") as middleware into my route, it executes. But this way I do not have access to res so I can send a message back to my front end. However, if I attempt to call it in the route callback function, it is not firing.
router.post("/login", function(req, res, next) {
passport.authenticate("local", function(err, user, info) {
console.log("Unreached"); // This is not logging
});
})
Here is my passport.use inside app.js
passport.use(new LocalStrategy({
usernameField: "portalId"
}, function(portalId, enteredPassword, done) {
var params = {
TableName: "MyTableName",
KeyConditionExpression : "PortalID = :portalID",
ExpressionAttributeValues : {
":portalID" : Number(portalId)
}
}
docClient.query(params, function(err, user) {
if (err) throw err;
let realPassword = user.Items[0].password;
bcrypt.compare(enteredPassword, realPassword, function(err, res) {
if (err) throw err;
if (res) {
return done(null, user);
}
if (!res) {
return done(null, false, { message: "Invalid Credentials" });
}
})
})
}));
Saw in some other post a snippet of code using the custom callback and he had (req, res, next) right after the passport.authenticate function. I added this and my code was being fired now.
I am trying to build an authentication panel for the MEAN stack using PassportJS. I have the following code for registering new users with email(instead of the default username) and password:
router.post("/register", function (req, res) {
var newUser = new User({
username: req.body.email
});
User.register(newUser, req.body.password, function (err, user) {
if (err) {
return res.render('account/signup');
}
passport.authenticate("local")(req, res, function () {
res.redirect("/account/profile");
});
});
});
However, when running the server, I am presented with a screen on which it is written Bad Request.
It can be assumed that the new user account is being successfully created as I am able to log in that account.
I believe that the error originates somewhere around here:
passport.authenticate("local")(req, res, function () {
res.redirect("/account/profile");
});
passport.authenticate is a middleware, which means that you have to call it with 3 parameters (req, res, next):
...
passport.authenticate("local", function(err, user, info) {
if (err) return next(err);
if (!user) return res.redirect('/login');
req.logIn(user, function(err) {
if (err) return next(err);
return res.redirect("/account/profile");
});
})(req, res, next);
...
Or use it inside post method:
router.post("/register", function (req, res, next) {
var newUser = new User({
username: req.body.email
});
User.register(newUser, req.body.password, function (err, user) {
if (err) {
return res.render('account/signup');
}
// go to the next middleware
next();
});
}, passport.authenticate('local', {
successRedirect: '/account/profile',
failureRedirect: '/login'
}));
exports.findt = (req, res, next) => {
const token = req.user.tokens.find(token => token.kind === 'twitter');
const T = new Twit({
consumer_key: process.env.TWITTER_KEY,
consumer_secret: process.env.TWITTER_SECRET,
access_token: token.accessToken,
access_token_secret: token.tokenSecret
});
T.get('https://api.twitter.com/1.1/users/search.json?q=Twitter%20API&page=1&count=3', (err, reply) => {
if (err) { console.log(err) }
res.status(res).json(reply);
});
};
this is part of my controller, duplicated from hackathon-starter node app.