Fastify has its own package to handle strategies, which is fastify-auth. Among its strategies include fastify-basic-auth and fastify-jwt.
NestJS has a wrapper for passport strategies; #nestjs/passport, along with its documentation. I don't think they have a wrapper for Fastify strategies. I'm not sure how I would go about implementing the strategies into the project.
In the end, I would like to do the following:
#UseGuards(AuthGuard('FastifyBasicAuth'))
#Post('login')
async login() {
/* Logic... */
}
Related
Does NestJS support middleware with gRPC? I'm following the example project here and then the middleware for logging the request entrypoint here.
In the example project it looks like there is an Express server along with the gRPC server. I'm using just a gRPC server.
const app = await NestFactory.createMicroservice<MicroserviceOptions>(...);
await app.listenAsync();
So adding the following to the main app module:
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes('*');
}
}
But nothing is logging.
Middleware is exclusive to HTTP handlers. If you need middleware-like functionality, it would be better to use one of Nest's enhancers (guards, interceptors, pipes, or filters). If you're looking to do some logging I'd suggest an intereptor as you have pre- and post- controller logic.
There's also my logging library Ogma which has a Nest package and interceptor already which might be useful to look at
So I replaced ExpressJS with Fastify, but my problem is Nest-Passport doesn't support fastify, do we have an alternative for Nest-Passport? or any solutions on how to secure RestAPI in nestJS using a token?
I dont kown if this is the correct manner. But if I change the default jwt extractor
ExtractJwt.fromAuthHeaderAsBearerToken
(described within the doc ) by a custom one it works.
const fromFastifyAuthHeaderAsBearerToken = (request: FastifyRequest): string => {
const auth = request.headers['authorization'];
const token = auth?.split(' ')[1];
return token;
}
There's no immediate Fastify NestJJS authentication package I'm aware of (I'm sure there's something out there), but I do have a sample of JWT authentication with Fastify and NestJS without Passport. The idea is to make use of Nest's #nestjs/jwt package or just jsonwebtoken directly, and create the auth tokens with that instead of delegating to Passport. This is actually the kind of approach I prefer, as I find Passport to be a bit too mystical sometimes.
I have question about node.js routes. Which routing version is correct?
First version it's a standard version in express.js:
router.get('/packages/:name', (req, res) => {
//my example code
);
Second version with TypeScript. This version is from typeorm init command.
export const Routes = [{
method: "post",
route: "/user",
controller: CustomerController,
action: "createUser"
}];
Which version is better and why? About the second version, how i can add custom middleware? What is difference between first and second version?
Both the approaches are same. When you have a lot of routes for a single point like root/apiv1/[here all the routes] then the second
one is preferable, if you have many dynamic routes, so its better to
go with the first approach.
Talking about the language, you can achieve both kind of routing in
plane JS and also in JS. But due to typecasting and validations,
preferred language is typescript and way of routing depends on the situation.
Talking about the middleware, for the first approach we will pass the
middleware just before the controller function, and for the second
approach, we are bascially creating structures for our routes and we need to
pass these routes to some route() end point, there we will
define the middleware just like we are doing in the first approach.
I am having two controllers, SocketController and ProjectController
SocketController has method getData(data)
ProjectController has method addProject(data)
I need to call addProject() from getData() method.
I tried using sails.controllers.ProjectController.addProject(data) but I got following error:
Cannot find method addProject of undefined
I searched for alternative ways to call another controller using services in Stack Overflow but that was of no help to me. Is there any other way to get this work?
Controllers are just Node modules that export public methods. You can require them like anything else. So assuming your methods are correctly exposed with module.exports, this will work:
/* ProjectController */
module.exports = {
addProject: function(data) {
// ...
}
};
/* SocketController */
// Assuming ProjectController.js exists in the same directory (default for Sails)
var projectController = require('./ProjectController');
module.exports = {
index: function(req, res) {
// ...
projectController.addProject(...);
}
};
Edit: I will add that using services is a better place to keep common functionality like your example. Services allow complex logic to be decoupled from the controller layer and reused by other areas of the application with ease. Controllers should generally be reserved for handling HTTP requests from the client and passing the data to the service or model layers for manipulating the database. I believe Sails also makes services global by default so you don't have to worry about confusing require paths.
Controller functions are also accessible through the global sails object, without use of require, however a function from ProjectController will be found under:
sails.controllers.project.addProject
instead of
sails.controllers.ProjectController.addProject
Anyways you might want to consider having shared functionality in either services or models, as was pointed out previously.
In a sails.js application is there a simple way of including express-middleware?
For instance extending the request object with express-validator.
Adding express-middleware in a sails application is simple.
create a new policy.
policies
|_
middleware.js / .coffee
Add Express MiddlewareYOUR_MIDDLE_WARE_FILE_NAME.js
Inside your middleware file we create the standard export for node.js
module.exports = require('middle-ware')(OPTIONS_GO_HERE) // See middleware docs for configuration settings.
Then once you have created the middleware you can apply it to all requests or a single controller by following the Sails.js convension.
Entire Applicationpolicies.js
module.exports.policies = {
'*':['middleware'] // node same name as file without extention
}
Single Controller Action policies.js
module.exports.policies = {
RabbitController:{
feed:['middleware']
}
}
First of all, #SkyTecLabs' answer is the proper way to do this. But I wanted to add that, in some cases, you may need to control your static files (images, client-side javascript, css, etc) as well (I just had to deal with this recently). In this case, you can apply middleware generically to every route.
As of Sails.js v0.9.3, you can do:
// Put this in `config/express.js`
module.exports.express = {
customMiddleware: function (app) {
app.use(require('../node_modules/sails/node_modules/express').basicAuth('balderdash', 'wickywocky'));
}
};
More here: https://gist.github.com/mikermcneil/6255295
In the case where you want middleware to run before one or more of your controllers or actions, you're definitely better served using the policy approach though!