I have some routes on my API. And have a middleware. Its creating bearer token and checking it. But i want some of my routes dont enter to that middleware so i can access without token. How can i make it ? My middleware :
app.use(async (req, res, next) => {
if (
req.path === "/api/v1/collection/byhome" || // I dont want that part.
req.path === "/api/v1/user/login" // Its working but its not looks like best solution.
) {
next();
} else {
const bearerHeader = req.header("authorization");
if (typeof bearerHeader !== "undefined") {
const bearer = bearerHeader.split(" ");
const bearerToken = bearer[1];
req.token = bearerToken;
jwt.verify(req.token, process.env.SECRETKEY, async (err, authData) => {
if (err) {
res.sendStatus(401);
} else {
next();
}
});
} else {
res.statusCode = 400;
const Response = {
message: "Invalid Token",
StatusCode: res.statusCode,
};
res.json(Response);
}
}
});
My Route :
app.get(
`/api/${version}/article/bycollection/:id`,
ArticleRoute.getbycollection
);
your way of doing it is correct you can make your code more readable by making an array of all the middleware you want to be out of scope of your middleware
const whiteListEndpoints = ["/api/v1/this", "/api/v1/this1", "/api/v1/this2"]
then
// your middleware
app.use((req, res,next) => {
//if the path was in the whitelist just call next function
if(whiteListEndpoints.includes(req.url)) return next()
// let the middlware do it's job
})
or you can change your express use
order
const firstRoute = app.use("/no_middleware", router);
app.use((req, res, next) => {}) // your middleware
const secondRoute = app.use("/with_middleware", router);
here the first router won't use the middleware since it has not yet been called.
You can use Express.Router
to achieve the desired result. With express router you can differentiate between routes and have different middlewares for each router.
Follow the steps given below:
middlewares/private.authenticate.js
function auth(req, res, next) {
// do auth stuff...
next();
}
routes/private/index.js
// private route handler
import { Router } from "express";
import auth from "./middlewares/private.authenticate.js";
const router = Router();
router.use(auth); // use auth middleware
router.route("/")
.get()
.put()
export default router;
routes/public/index.js
import { Router } from "express";
const router = Router();
router.route("/")
.get()
.put()
export default router;
import express from "express";
const app = express();
import PublicRoutes from "./routes/public";
import PrivateRoutes from "./routes/private";
// public routes path
app.use("/api/public", PublicRoutes);
// private routes path
app.use("/api/private", PrivateRoutes);
You can create a route express.Router()
and set this to a path
, this router have all auth, then create a second express.Router()
and this without auth.
var router = express.Router();
// your code for API auth...
router.get('/api/v1/collection/byhome',myMiddleware, (req, res, next) => {
res.send('Hey There');
})
app.use('/api', router);
var routerGuest = express.Router();
//
routerGuest.get('/', (req, res, next) => {
res.send('Hey There');
})
app.use('/guest', routerGuest)
for authentication, I recomend to make a separate middleware and then pass it to our route
function myMiddleware(req, res, next){
const bearerHeader = req.header("authorization");
if (typeof bearerHeader !== "undefined") {
const bearer = bearerHeader.split(" ");
const bearerToken = bearer[1];
req.token = bearerToken;
jwt.verify(req.token, process.env.SECRETKEY, async (err, authData) => {
if (err) {
res.sendStatus(401);
} else {
next();
}
});
} else {
res.statusCode = 400;
const Response = {
message: "Invalid Token",
StatusCode: res.statusCode,
};
res.json(Response);
}
}
}
I think with this you may have some idea to do it :)