Passing additional data to Middleware
josezone opened this issue · 2 comments
josezone commented
I am using
- inversify 5.0.1
- inversify-binding-decorators 4.0.0
- inversify-express-utils 6.3.2
The code I am working on can be seen at this Link
The Problem
I need to pass an additional parameter to the Middleware so that it will act as a factory,
Example, I need to pass a role onto a middleware so that the system can check if the user has permission to access the API
an example we need to create a middleware as follows
@provide("roles")
class RoleValidator extends BaseMiddleware {
role(role){
return handler(req: Request, res: Response, next: NextFunction) {
if(req.user.role === role){
next();
} else {
res.end();
}
}
}
}
And the middleware is called by a controller
@controller('/test')
class UserController extends BaseHttpController {
@httpPost('/', "roles=>'currentRole'")
private test(
@requestParam('param') param: string,
res: Response,
next: NextFunction
){
//code
}
}
How can this be achieved, this is a common scenario, that has to be used. Is it that, the feature is not supported.
hazeos commented
You can implement it like this:
-
Pass functions to endpoint decorator
@httpPost('/', authenticateToken(), authorizeUser(['administrator']))
-
Function example
export const authenticateToken = (/* PARAMS HERE */) => {
return async (req: Request, res: Response, next: NextFunction) => {
const authHeader = req.headers.authorization;
const token = authHeader && authHeader.split(' ')[1];
if (!token) {
return next(new AppError(HttpStatusCode.UNAUTHORIZED, 'error', 'No token'));
}
verify(token, process.env.ACCESS_TOKEN_SECRET, (error, user) => {
if (error) {
console.error(error);
next(new AppError(HttpStatusCode.FORBIDDEN, 'error', 'Invalid or expired token'));
}
req.body.user = user?.user as IJwtUserPayload;
next();
});
};
};
talfreds commented
You can implement it like this:
- Pass functions to endpoint decorator
@httpPost('/', authenticateToken(), authorizeUser(['administrator']))
- Function example
export const authenticateToken = (/* PARAMS HERE */) => { return async (req: Request, res: Response, next: NextFunction) => { const authHeader = req.headers.authorization; const token = authHeader && authHeader.split(' ')[1]; if (!token) { return next(new AppError(HttpStatusCode.UNAUTHORIZED, 'error', 'No token')); } verify(token, process.env.ACCESS_TOKEN_SECRET, (error, user) => { if (error) { console.error(error); next(new AppError(HttpStatusCode.FORBIDDEN, 'error', 'Invalid or expired token')); } req.body.user = user?.user as IJwtUserPayload; next(); }); }; };
I don't think it's possible with BaseMiddleware
, so that you have access to http context, right?