I have a NodeJS Backend running, which uses the express framework. In the frontend I use Angular. In the past I build two Docker Containers (one frontend, one backend). Now I want to build just one container, in which NodeJS run as usual. But it should also provide my frontend. It is working, so here is my code:
import express = require("express");
import session = require('express-session');
import dotenv from 'dotenv';
dotenv.config();
const app = express();
const port = process.env.PORT || 80;
...
const isOnline: RequestHandler = (req: express.Request, res: express.Response, next: express.NextFunction) => {
if (!req.session.user) {
return res.redirect('/auth/login?rd=' req.originalUrl);
}
next();
};
...
app.use('/api', isOnline, apiRoutes);
app.use('/auth', authRoutes);
app.get('*.*', express.static(path.join('./', 'dist'), {maxAge: '1y'}));
app.get('*', isOnline, (req: express.Request, res: express.Response) => {
res.status(200).sendFile(`/`, {root: path.join('./', 'dist')});
});
app.listen(port, () => console.log('API running on port ' port));
Code explaination
So actually there are three types of routes. The API, the Authorization and the Frontend paths. The API and the Frontend should be only accessible by users which are authorized. The Authorization is available for everyone.
Issue / Question
The issue is, that I provide all files from the dist folder (in which my build angular app is located), which has a dot (so all file names). And when I open the app (example.com), I will directly redirect to the auth route. This means the middleware is working. But if add the index file to the path (example.com/index.html), I have access to the app directly, because it is provided by the . route.
Solution Ideas Is there maybe any way to exclude the index.html from the wildcard statement (or do I stop providing angular by this)? Can I catch the route exmpla.com/index.html and redirect to the base path? Or is there any other way to protect my whole angular app by my middleware?
CodePudding user response:
you might completely close public (dist) folder:
app.get('*.*', isOnline, express.static(path.join('./', 'dist'), {maxAge: '1y'}));
leaving publicly open only api and login route
and on the login route in authRoutes
, render a login page with some minimal inlined css and form or javascript to handle the login:
authRoutes.get('login', /*res.sendFile with styles and login form*/)
authRoutes.post('login', /*handle login*/)
//...