Secure my ExpressJS server Routes, they will accessed through cURLs - node.js

I'm in need of some advice on what's the best method I can use so that the routes on my server are only accessed by certain users.
My server has some simple routes"/example" and I'm using Express JS to write these routes. The people who will access these routes are a few and they will mostly be doing it from terminal with a curlcurl 123.45.678.901/example but I want to make it secure so that only a certain group of people can access that route.
What should I do? I'm new with this so I was looking into maybe adding a custom header to the curl but I don't know how to check in the route for that custom header and then I thought that might be too simple so I'm wondering if there's a better way that giving the users a "password". Grateful for the advice!

You need to require a credential in order to access the protected routes. The credential can be in the form of a token or password in a custom header, in a query parameter or a token in a cookie.
It's best not to put security credentials in query parameters and obviously, you should be using https to protect the credentials during transport.
If the route is only accessed via CURL, then a custom header containing the credential is probably the most straightforward way to do it.
For express on your server, put all routes that require auth on a specific router and have middleware that verifies the credential before passing control to the routes.

Related

User session between Express+Nodejs and clients using Firebase

what's a common approach of storing user sessions with Nodejs+Express and Firebase auth? I have Android and Ios app that I'd like to use the same logic on (later web as well), so I'd get the JWT token. I'd like to use that token as authorization for requests. Also I'd like to keep the user sessio and not require them to relogin again. I am not sure how to go about this, all of the Express Session resources I've found were on topic of web and cookies. I've stumbled upon MongoConnection a library for Express that presumably stores the sessions in the MongoDb, but how does the session work with non-web requests? Can anyone help me clarify this, I am aware that I am missing the point here as there is certainly an easy way to verify incoming requests and also have a session for the user to not have to login everytime.
Preferably I'd like to have an easy way to have endpoints that require JWT token access. Besides that also have a session of sorts. There is a function to verify tokens in the Firebase Admin SDK for Nodejs but it seems really weird to have to check the token manually in every request.
I treat sessions on the backend and front end entirely separately as I predominantly make RESTful apis. On the front end you can handle sessions however you like, e.g. you can start a session when a user authenticates with firebase auth, and set the user role maybe based of attributes on the firebase auth user. Use cookies, do whatever you prefer.
Then on the backend, on every endpoint just decode the token, verify it, check that the user has access to the resource they are requesting etc. Its common to write your own middlewares so that you dont have to repeat the decoding code. For further info on this approach, this might help. Its not weird to check the token manually on every request, its common practice to guarantee the authenticity of the request. Hope this is of some help.
To sum up, treat your front end session entirely separately from the backend. On your express server on the backend, on any protected endpoint decode and verify the token to determine if the user has access to the resource.
Backend sessions with firebase are a bad idea (due to it been serverless), its better to create a stateless restful api.

Node JS Express secure route

I want to have some kind of auth to make protected routes.
For example, the GET /forecastweather should be protected. While the GET /generalweather should not.
I read the express 4.x documentation (https://expressjs.com/en/4x/api.html) but I can't find an authentication function. I also looked in the req (https://expressjs.com/en/4x/api.html#req) documentation to see if there is an attribute to request I can use.
If I'm right express had basic auth function, but it seems to be gone. What is the best way to protect routes by some kind of bearer token.
There is no "best" way to do authentication. There are just multiple different ways and you have to decide which fits your situation the best.
First, you need to decide how you're going to deliver your credential which likely depends upon what type of client you're using.
Token in a cookie (often works best for browser access)
Token in a custom header (often used for programmatic access for APIs)
Token in query parameter (not as common)
Once you decide how the token is going to be delivered, you then have to figure out how the client is going to get their token. This would typically be some sort of form submission that contains credentials (such as username and password) and the return from a successful verification of those credentials would be the token.
To process this form, you'd create a POST request handler in Express and verify the credentials, returning a token if the credentials are valid.
Then, within Express, you'd create a router that contains the authenticated routes and add some middleware to that router that verifies that a valid token is present on the request before allowing the request to proceed. This will protect all the routes on this router.

Use of express-session and JWT

I have a bunch of questions about express-session and JWT in a project that I am building.
I have an Express API server that I want to protect using some sort of API key, to make sure only authorized applications can access to my data. JWT would probably get the job done. However I also need to authenticate users and restrict them from accessing certain parts of the data (e.g. role-based permissions) using express-session.
The frontend server would be a Next.js instance, which would save and use the cookies for express-session. The session would be stored in a MongoDB instance.
Would I be able to use both authentication methods in the same project? Would it be secure? Is there any easier approach to this? How could I implement the permissions?
Any help and tips would be appreciated.
JWT and Express-Session both accomplish the same thing. The difference is a browser does not allows a http-only cookie to be accessible through javascript. At then end they are both used for the same end.
The jwt should be related to a session of a user, therefore the users permissions are the ones that matter. These can be implemented in a DBs and related to the user. Does he has this permission or does his role has this permission is the middleware you would put on the routes.
In case of doing it with express-session, I would personally take the same approach.

How to distinguish between user types when authenticating with JWT

In my app (Mongo,Express,Node,React), I'm currently authenticating users from the client to the server using JSON Web tokens. However, I want to be able to have two different types of users access different halves of the app. What is the best way to go about this? I currently have both types of users saved in the same model with a boolean that differentiates them. To clarify, different types of users would be able to access different API's as well as different portions of the client side app.
Is there a package that handles this? JWT feature?
There are 2 ways that you may do this:
When you are encoding the JWT token, encode the user role also.
When you decode the JWT token and get the user's ID, for example, query your data store to get that user's role.
Most of the packages will allow you to define what you want to encode.
Tips:
Always set an expiry on your tokens. It's simply a date stored on
the JWT. When you decode the token just make sure that the date is
in future, if not deny access.
Create a middleware that checks the user's role. For example:
router.get('/restricted-area', requiresAdmin, (req, res, next) => {
// only admin can access this
});
function requiresAdmin(req, res, next) {
if(req.user.admin !== true) {
res.status(401).end();
} else {
next();
}
}
Wanted to add a little to the suggested answer. A lot I am taking from how Auth0 uses jwt. You might want to play with it so see how they handle authentication and protecting their routes. Another thing that really helped me understand ways to use jwt was playing with the debugger on the jwt website.
Allowing users to access different API endpoints
A jwt token can be decoded by anyone. Anyone can see what is on the token. The important part of a jwt is that it has a signature. If someone wanted to take a token, change the information and then access your api, then the signature would be messed up and that token should be rejected.
All you need to do is create a route middleware. If a route is protected the user sends the jwt in the header. The middleware will do 2 things:
Check the signature of the token to ensure the token is valid and has not been tampered with.
Decode the token to see what is on the JSON. Since a jwt is just a JSON you can add any property to it you want. Add a property permissions and set what level that users permissions are. Here is a tutorial from auth0 about how real life companies like slack could use jwt tokens to define what a user can and can't do. A lot of the same principles apply to exactly what you want to do. Auth0 with multi tenant apps
How can I restrict users client-side using React?
I saw this question in the comments and will throw the answer here in case anyone was interested. If someone really wanted to, they can take their token, change it, and get to any visual component (in react). The reason that is the case is you don't want to keep any token signature secrets on your client. But even if someone did change their token, they wouldn't be able to do any damage. If they tried to send a request to the server, their token would be rejected and your api would be protected.
React Router and Dynamic Routing
For the 99.9% of your users that don't mess with their token, the best way to decide what parts of the site they are allowed to use is by using react-router. Since React is a single page application there is only one static html file that will send your build to the client. With other frameworks different routes on your server will send a different page at different static endpoints. To mimic this page behavior with react, it is very common that people use React Router. React Router creates dynamic routes so when users insert endpoints into the browser it can mimic how typical static sites work.
It can also be used to restrict users from accessing certain components. Once a user logs in, you can send the decoded token information and save it to your react state. One of those would be your permissions parameter. With react router, when a user attempts to navigate to a location that requires permissions you can reference their state and redirect them either to the protected component or back to an authorized catch, back to where they came from, the login page, etc. Basically wherever you want.
Here is a, slightly confusing implementation on the react router documentation site about implementing restricted endpoints.
Another tutorial from auth0 using react router to restrict users. Scroll to the header Process the Authentication Result

ReST API: Should I associate the access token with a user in my database

I am building a secure ReST API on a nodeJS server so that my Android application can access the data on my site. Based on reading some other posts, I've come to understand that I should use an access token. So my idea is to do the following:
1) When the user logs in on the Android app, the app sends a request to /api/login on my site, providing the username and password (this of course needs to happen over SSL to guard against eavesdropping).
2) My server validates that the username + password match, and, if so, responds with an access token.
3) The app uses this access token to make all subsequent requests to my API.
My question is should I store the access token in the database on my server? Specifically, should I store the fact that the access token is associated with that particular user? Most tutorials I looked at did not do this, but if I don't, then what is to stop a user with this access token modifying or viewing the data of another user? Don't I need to pair an access token with a user in my database?
try using this library, i did the same type of project and this life saver was my solution.
If you need to build a secure API the things are little more complicated. You need to sign the access token with a private keystore.
Would it be a option to use a authentication service like Auth0? They are generating a JWT token for you and you only need to validate this token. The API is completely stateless. You can find a lib for almost any programming language on their website.
What you want to do is exactly HTTP Sessions do.
So, I think you can just use HTTP Session functionality It's already implemented in WAS frameworks like Django, Spring etc. If NodeJS provide session functionality, Just use session functionality in the framework. If not, look up the HTTP Session library. Maybe you can find many library that treat session implementation.

Resources