http basic authentication with different rights - node.js

I am in middle of a development, and havent so far created user authentication in my node.js application,however I have an admin back-end where I do not want the users provided with the username and password.
I am looking for a way to implement basic http authentication but depending on the credentials provided, they can or can not go to different areas of site, in short: I want different credentials for admin page.
Any help will be appreciated.
Thanks and regards,
Babar

As I understand it you want two different types of testers. One to test frontend, but not affect backend and one that also affects backend.
I would actually run two instances of Node and point the testers to two different urls.
And in your routes you check the environment, giving fake responses to "testers1" and actual backend respones to "testers2".
Like:
NODE_ENV=simulated node server
function (req, res) {
if (process.env.NODE_ENV === 'simulated') {
// Give fake response
} else {
// Get from backend
}
}

Use multiple location blocks and separate access files or something like this:
location /test/ {
auth_basic "Test";
auth_basic_user_file /access.txt;
root '/webroot/$remote_user';
}

Related

What is the best way to conditionally serve static files in Express?

I'm building an application that has two separate parts to it, which on the frontend I am building as two separate Angular apps. I am doing it this way so that I can better divide control access to he codebase and not unnecessarily give some team members access to code they do not need.
So there are two separate applications, served from the same NodeJS server. The app that is served depends on whether the user is logged in. If they are a guest user, they get one version app, if they are registered user they get a privileged version of the app with more features.
How can I conditionally/dynamically serve static files in Express, so as to say, "if User1 is a guest, serve Application A, otherwise serve Application B"?
If it's just one file you're talking about serving (e.g. app-1.js or app-2.js) then you don't need express.static. You can just handle the request in a normal route handler with res.sendFile like so:
app.get('/get-app', function(req, res) {
if (userIsLoggedIn()) {
res.sendFile('/path-to-logged-in-app.js')
} else {
res.sendFile('/path-to-logged-out-app.js')
}
})
More about res.sendFile here.
If you want to serve multiple files via express.static, you'll need two instances of express.static middleware, and another piece of middleware on top of that to modify the request url depending up on the user's logged in status. Maybe something along the lines of the following:
// Middleware function to modify the request url based on user's status
function checkUser(req, res, next) {
if (userIsLoggedIn()) {
req.url = `/app-1/${req.url}`
} else {
req.url = `/app-2/${req.url}`
}
next()
}
// Set up the middleware stack
app.use(checkUser)
app.use('/app-1', express.static(path.join(__dirname, 'app-1')))
app.use('/app-2', express.static(path.join(__dirname, 'app-2')))
More about writing your own middleware here. You also might want to add some logic in checkUser to only prepend to urls requesting static files (e.g. request urls to /assets/foo.js get the prepend treatment but requests to /api/some-api-function do not).
All that said, I'm not that familiar with Angular but I'd suggest investigating other ways to serve logged in / logged out content. I'm assuming there is some concept of components or "views" in Angular, and it's probably a lot cleaner to just render a "LoggedIn" or "LoggedOut" component/view vs. sending a whole different "app".

Best way to handle API calls from frontend

Okay, so atm i have a frontend application built with Nuxt JS using Axios to do requests to my REST API(separate).
If a user does a search on the website the API URL is visible in XMLHttprequests so everyone could use the API if they want to.
What is the best way of making it so that only users that search through my website gets access to the API and people that just directly to the URL gets denied. I suppose using some sort of token system, but what is the best way to do it? JWT? (Users never log in so there is no "authentication")
Thanks!
IMO, you CANNOT block other illegal clients accessing your
backend as you describe that the official client and other illegal have the same knowledge about your backend.
But you can make it harder for illegal clients to accessing your backend through some approach such as POST all requests, special keys in header, 30-minutes-changed token in header and server-side API throttling by client IP.
If the security of the search API is really important, authenticate it by login; if not, just let it go since it is not in your critical path. Let's focus on other important things.
I'm in the same "boat" and my current setup is actually in VueJs but before even come to StackOverflow I developed a way to actually, the frontend calls the server and then the server calls the API, so in the browser, you will only see calls to the server layer that, the only constraint is that the call must come from the same hostname.
backend is handled with expressJs and frontend with VueJs
// protect /api calls to only be originated from 'process.env.API_ALLOW_HOST'
app.use(api.allowOnlySameDomainRequests());
...
const allowHostname = process.env.API_ALLOW_HOST ||'localhost';
exports.api = {
...
allowOnlySameDomainRequests: (req, res, next) => {
if(req.url.startsWith('/api') && req.hostname === allowHostname) {
// an /api call, only if request is the same
return next();
} else if (!req.url.startsWith('/api')) {
// not an /api call
return next();
}
return res.redirect('/error?code=401');
},
...
};
In our case, we use Oauth2 (Google sign through passportJs) to log in the user, I always have a user id that was given by the OAuth2 successful redirect and that user id is passed to the API in a header, together with the apikey... in the server I check for that userid permissions and I allow or not the action to be executed.
But even I was trying to find something better. I've seen several javascript frontend apps using calls to their backend but they use Bearer tokens.
As a curious user, you would see the paths to all the API and how they are composed, but in my case, you only see calls to the expressJs backend, and only there I forward to the real API... I don't know if that's just "more work", but seemed a bit more "secure" to approach the problem this way.

Easiest way to password protect my Laravel app online for development purposes

I am wanting to password protect my laravel application, ideally just on the deployment server (I'm using Fortrabbit), however, I don't mind logging in to my local development server.
I initially thought a route filter would suffice, but this doesn't seem to work:
Route::get('/', array('before' => 'auth.basic', function()
{
// Only authenticated users may enter...
}));
At the top of my route file, this is completely ineffective, however, at the bottom of my route file, it does seem to work, but if I physically type a sub-directory in, i.e. localhost:8888/user/ it seems to override it.
Any guidance as to how you show your applications to clients (without Google, anyone else finding them), would be hugely appreciated.
You need to apply the 'before' auth filter to all routes that require it.
The reason why it does not work at the top of your routes file is probably because you're specifying another GET route pointing to '/', whereas at the bottom of the file it will work fine since the route with auth.basic overwrites it.
You can do something like this to specify that all routes should be protected:
Route::group(array('before' => 'auth.basic'), function()
{
// all your routes placed in here will be protected by auth.basic
});
Can you make a group around your routes.
http://laravel.com/docs/routing#route-groups
(as suggested before me I see so I borrowed the code (give credit to that poster))
Route::group(array('before' => 'auth.basic'), function()
{
// all your routes placed in here will be protected by auth.basic
});
or
maybe you can use a patern based "*" wildcard at your routes?
Route::get('*', array('before' => 'auth.basic', function() {
// Only authenticated users may enter... }));
http://laravel.com/docs/routing#route-filters
Is a .htaccess file possible at fortrabbit?
than maybe use: http://www.htaccesstools.com/articles/password-protection/
Sometimes I use Pagekite to temporarily allow access to a site on my local development box : https://pagekite.net/

Prevent users from accessing subdomain in Express

I am very new to web development and Node.js / Express. I have an Express server. In my client I send a GET request for some data in the DB. The GET request is handled by
app.get( '/pathname', controller.getsomedata );
The problem is, the user can now type in the URL domainname.com/pathname in the browser and get directed to that pathname. If they add in a certain queries domainname.com/pathname?query, they are able to retrieve data from the DB (this is supposed to happen), but I would prefer if GET requests to /pathname only occur from within the client code, not when the user enters it in the browser.
Is there a better way to do my GET request? Or is there a way to restrict users from accessing /pathname.
I apologize for the newbie question, but I don't know how to word it well enough to do a google search for the solution. Thank you!
It's impossible to do that. If your client-side code is able to access something, malicious user can do that as well.
You can mitigate the issue by using custom HTTP header or something like that, but it's better to validate all data on the server-side.
Allow whole client request as DB query may cause security issues. So be sure to validate query parameters and use them as DB query conditions.
If you want to query DB freely from HTTP query parameter, you should prepend authentication/authorization to the route.
app.get( '/pathname', function(req, res, next) {
if (confirmThisRequestIsFromMe(req)) {
next();
} else {
res.send(401);
}
}, controller.getsomedata );

Nodejs User login System

Am looking for some information on how to create a node.js login system, I have came across a lot of examples using express.
But am looking for some direction on how to do this without using express.
The main reason behind this is that my login webpages will be hosted on an apache server and my node.js server application will be running on a different server running mongoDB.
Any help in pointing me in the right direction would be great.
Thanks,
Iain
I know you said you didn't want solutions using express. But you may want to checkout Drywall for other inspiration. There are a lot of problems we solved and I'm sure there are some take-a-ways you could use.
Drywall Aqua - A website and user system for Node.js:
https://jedireza.github.io/aqua/
SweetAuth
A lightweight, zero-configuration user authentication module which doesn't depend on a database.
https://www.npmjs.com/package/sweet-auth
It's simple as:
app.get('/private-page', (req, res) => {
if (req.user.isAuthorized) {
// user is logged in! send the requested page
// you can access req.user.email
}
else {
// user not logged in. redirect to login page
}
})
With this, you have the flexibility to point your front end pages in a separate server to a nodejs in another server.

Resources