I'm using node, express and connect for a simple app and have basic HTTP auth implemented as follows (lots of code left out for brevity):
var express = require('express'),
connect = require('connect');
app.configure = function(){
// other stuff...
app.use(connect.basicAuth('username', 'password'));
// other stuff...
};
I've tried googling and even attempted implementing my own auth, but I can't figure out how to skip this auth for just one route.
I'd really appreciate it if anyone offer any help with this?
If you don't want to use authentication for all routes, you should add the auth function as middleware to each individual route like so:
app.get('/mysecretpage', basicAuth, function (req, res) {
console.log('you have to be auth to see this page');
});
Here is a regular route without auth:
app.get('/sample', function (req, res) {
console.log('everybody see this page');
});
This link may be useful for you also: how to implement login auth in node.js
Related
I have a node express app that uses keycloak authentication to secure all API endpoints. Express middleware has been set up for authentication to make sure that each incoming request from the front end has the appropriate keycloak token. I need to make a post request from my node app to a third party backend API to subscribe users to an email service that uses a different authentication method which my middleware would not work with.
What would be the best practice for making a request from the third party API? I am considering creating a new express instance and use a separate middleware specific for that post request. Is this an ok thing to do or is there a better way?
Here is a simplified version of my node app. See the
index.js
import { authmware } from "./authmware";
import express from "express";
import { router } from "./router";
const app = express();
authmware(app);
router(app);
app.use((err, req, res, next) => {
logger.error(err.message);
const code = err.code ? err.code : 500;
const message = err.message ? err.message : "Internal Server Error";
res.status(code).json({ error: message, success: false });
});
export default app;
router.js
import express from "express";
import createProfile from "../../controllers/createProfile";
const router = express.Router();
router.post("/", createProfile);
export const router = (app) => {
app.use("/api/v1/createProfile", router);
};
controllers/createProfile.js
const createProfile = async (req, res) => {
// ... Do some stuff
// ** make request to a different api here **
await makeThirdPartyApiRequest();
}
How would I make this third party api request that uses a different style of authentication?
This is a very common use case. You can use 10 third party APIs in your node server and all having different authentication mechanisms irrespective of the auth you are using for your client requests.
await makeThirdPartyApiRequest();
// http request to API
// attach proper auth headers (API key / jwt / basic auth / oAuth token). This will be based on the authentication method the API is offering.
}
Update based on your recent comment:
The API should have some documentation on how to authenticate using the user key and secret key. For example: Google APIs just require you to send API key with request https://cloud.google.com/api-keys/docs/overview
Somewhat new, please bear with me. Trying to use passport to authenticate only specific routes in a website. The routes are in a separate file called blog_a.js. I have the following functions created in the main server.js file:
function checkAuthenticated(req, res, next) {
if (req.isAuthenticated()){
return next()
}
res.redirect('/login')
}
function checkNotAuthenticated(req, res, next) {
if (req.isAuthenticated()){
return res.redirect('/')
}
next()
}
However, I'm trying to pass the above functions into the blog_a.js module, so I can use them as middleware to protect the routes within that module.
I have tried to use module.exports = {checkAuthenticated, checkNotAuthenticated} at the bottom of the main 'server.js' file, and then use a let server = require('../server.js') line to import these functions to the module that contains the routes I want to protect.
However, the above server variable comes back as undefined, and I've tried several permutations / destructuring methods to try to import it. All to no avail, I keep getting the routes failing due to the "undefined" object--Error: Route.get() requires a callback function but got a [object Undefined].
How can I set up the authentication in the server.js file but then pass its authentication functions to be used as middleware within an individual route file?
I looked at this solution, but it doesn't clearly explain how to get the middleware functions from one module--server.js--to another module--blog_a.js.
I got the following response on Patreon from Kyle of Web Dev Simplified, and it worked like a charm!
"You should be able to just create another file that is called authMiddleware.js or something like that. Then in that file define and export the functions at the end (module.exports = { function1, function2 }). Now in the places you need those functions you should be able to import them like so (const { function1, function2 } = require('./authMiddleware'))."
So I followed Kyle's advice and created the following separate file authMiddleware.js:
function checkAuthenticated(req, res, next) {
if (req.isAuthenticated()){
return next()
}
res.redirect('/login')
}
function checkNotAuthenticated(req, res, next) {
if (req.isAuthenticated()){
return res.redirect('/')
}
next()
}
module.exports = { checkAuthenticated, checkNotAuthenticated }
... and then used the following require statements to get access to the functions:
-in main server.js --> const {checkAuthenticated, checkNotAuthenticated} = require('./authMiddleware.js')
-in router file blog_a.js --> const {checkAuthenticated, checkNotAuthenticated} = require('../authMiddleware.js')
Thanks!
I created a service in express to send emails, now I'm implementing a middleware for jwt authentication, it is already working, now I would like this middleware to be called automatically for any api I have or the ones I will cre
I tried to do the following assignment on my root, checkToken is my function on middleware
const app = express();
app.use(checkToken, require('./middlewares'))
app.use(`${config.URL_BASE}/email`, require('./apis/email'))
.
.
.
currently to call the middleware i'm doing, its works very well
router.post('', middleware.checkToken, async function (req, res) {
const {
type: typeCode,
.
.
.
its works very well, but my other api dont call the middleware, i didn't want to explicitly call again
Other api
router.get('/health', async (req, res) => {
res.status(200).send({ message: 'Ready.' })
})
To have middleware called for all routes, just do an app.use(yourMiddleware) before any of the routes are defined.
To have middleware called for one set of routes, but not other routes, put all the routes you want the middleware to be called for on a particular router that has a path prefix that only matches a subset of your routes. Then execute the middleware on that router before any of its routes are defined.
Here's an example of the 2nd option:
const express = require('express');
const app = express();
// load and configure api router
app.use('/api', require('./apiRouter.js'));
app.listen(...);
Then, inside apiRouter.js:
const router = require('express').Router();
// middleware that is called for all api routes
router.use(myMiddleware);
// define api routes here
router.get('/list', ...)
module.exports = router;
router.use() mounts middleware for the routes served by the specific router.
router.use(checkToken)
router.get('/health', getHandler)
router.post('/', postHandler)
module.exports = router
I am building a webapp in the form of a network of sorts with basic CRUD actions. I am in the process of splitting up my router files as they are becoming rather large.
I have an 'actions' route which does things such as selecting an in individual post to view, voting on a post, viewing a profile and commending a user. I cannot seem to find a way to allow me to split these 'action' routes into a seperate file and then use them as needed in the main route.
//index.js file in routes folder
var express = require('express');
var router = express.Router();
//main route
router.route('/feed')
.get(function(req, res, next){
//some code here
}
//actions.js file in routes folder
var express = require('express');
var router = express.Router();
//vote route
router.route('/vote/:id')
.post(function(req, res, next){
//some code here
}
//item route
router.route('/item/:id')
.get(function(req, res, next){
//some code here
}
I'd like to be able to use the action routes inside of the feed routes (and other routes) So I can do things like
POST /feed/vote/postid12356
GET /feed/item/itemid123456
or even in another route called 'private-feed' using the same actions from the actions route
POST /private-feed/vote/postid12356
GET /private-feed/item/itemid123456
Without having to have these actions repeated in many routes.
Is there any way in express that this can be done?
You can extract your route handler into a separate file, let's call them controllers and then reuse the logic in some of the routes:
//controllers/action.js
module.exports = {
get: (req, res, next) => {
//your post logic
}
}
///routes/item.js
const ActionController = require("../controllers/action");
router.route('/item/:id').get(ActionController.get);
module.exports = router;
I believe in express 4.0 this is the way for creating router-level middleware, is this a good approach creating multiple instance of express.Router?
var userRouter = express.Router();
var paymentRouter = express.Router();
userRouter.get("/login", function (req, res, next) {
res.send("okay this is route")
});
paymentRouter.get("/pay", function (req, res, next) {
res.send("okay this is route")
});
app.use("/user" ,userRouter);
app.use("/payment" ,paymentRouter);
Separate routers can be used to modularize your application.
In your case, it looks like you have (at least) two distinct parts of an API or web app, a user part and a payment part:
app.use("/user", userRouter);
app.use("/payment", paymentRouter);
It's perfectly reasonable to use two separate routers for this.
Usually, each router is modularized even further by placing them in separate modules, that contain the specifics for that router:
app.use("/user", require('./routers/user'));
app.use("/payment", require('./routers/payment'));
So you get a nice separation of concern.
The Express documentation also touches on this topic here.
Really depends on what you want to achieve.
The normal way is to have just one router that is used to define your routes.
Please explain better why you would like to have more routers.