Clean Architecture: how to properly authenticate users - node.js

I am making a project using Express and Nodejs.
I am learning how to implement learning how to implement clean Architecture properly.
I've made so far a Entity whose is a Balance (income/outcome).
But, in order for a particular user to be able to insert a new Balance, it's needed to be logged in.
So, in the Controller, I am receiving a Request which has a body with the income data and headers with the authorization token.
This controller makes the validations and forward the body as a DTO to the CreateBalanceUseCase.
My problem is that when i reach the CreateBalanceUseCase, I should call the data-access in order to save the data on the Database. But, the authorization token should be validated calling the AuthorizationDataAcess in order to find a user with same authorization token. But doing so, I violate the Clean Architecture I guess, right? Because I am trying to access the data-acces of the Authorization(aka User) inside the BalanceUseCase.
Also, on my database, I have a 1-n relation of the UserId with the Balance. So I can know what balance belongs to what user. So, also in order to save a Balance, I need to get the userId.
My second approach was create a Express Middleware that authorize the client and returns a userId, so whatever I must do through the app that needs authorization, It must use this middleware.
The problem is that I must access the data-access layer on the presentation layer
Whats the best practice in this situation? Or am I getting the Clean Code Architecture all wrong?
If there is any code or something else I could do to clarify more my question, feel free to comment it out.
Best regards.

Related

Should login and get profile be two different api endpoints?

I am designing api for mobile application.
I am not sure should I have one endpoint login which will return tokens & user profile
Or have two endpoints and after login call getProfile endpoint.
I saw that people mostly use second option but I don't see benefit of that approach?
Thinking in terms of the single-responsibility principle (which basically says "API methods should do one thing really well"), I'd suggest separating these into two separate things:
POST /login would set up a session and return the session ID to be used in subsequent requests.
GET /profile would return profile information provided a valid session ID is provided.
There are obvious benefits along the "happy path" for combining these, mainly the fact that after a login operation completes, you automatically provide the user with the data they most obviously would want next (who the user is). Why waste an extra API call to find it out, right?
If that's all your API will ever need to support, then there's no reason to separate these. But there are a couple cases I can think of for why you might want them separate:
What if an existing and already logged-in user wants to fetch the latest profile information? This means you must support GET /profile anyway (or have them POST /login again which is wasteful).
What if profile information is already cached and the POST /login API call is only happening to re-authenticate the user inside the app to complete an action? You'd be wasting bandwidth by sending data that's not needed.
Additionally, testing is usually a bit easier when you have each API method doing the one thing they imply they do (POST /login logs the user in, GET /profile fetches the current logged-in user's profile).

How to secure the update operation in this scenario

I have an app that recommends gifts to the user, after they answer a couple of questions. In the case that the user likes or dislikes a gift, I need to send an update request to the db to update it's 'liked' field. Users are not required to sign in order to like/dislike questions. The app is built using Angular and used Express at the backend to do the CRUD operations.
My question was, is there any way this operation can be done in a secure way, so that the user can not open the dev tools and get the info which would enable them to send repeated requests or anything like that? Is there anything I can change in the Express code? Or would I need to change the security rules?
Express should have a way to identify duplicate request. User id or some kind of token should be with request. But I see that sign-in of user not required in this case.
You can generate a temporary token every time some gifts are shown to user. This token should be generated and saved temporarily on express and you can send it with gifts data. So now when your frontend send request for like/dislike, this token will be in request.
So now express will do following steps
Checking if temp token is valid (it can match it with saved tokens)
If valid then it will update the database (like/dislike)
After successfully update it will remove that temp token.
So now, even if user send duplicate request it will be rejected by express as temp token will be not valid.
I hope it will solve your problem.

How can I protect a express route without authentication?

I'm trying to implement a GET method with Express in my nodeJs application.
I'd like to do something like this in order to display user data :
router.get("/user/:idUser", (req, res) => {
The user doesn't need to be authenticated in order to execute this code. However I don't want that anybody can execute this request with a user id of someone else. Because he could see data he's not supposed to see.
How could I proceed ? I thought about using some encryption process to have something like :
/user/PdfgdfJFDGTfrfgdsf
Your question isn't really making sense. You don't want authentication, but you only want a user to be able to view their own data so nobody else can view it.
The ONLY way to solve that is by using some form of authentication. The user has to prove to the server that they are allowed to view that data before the user renders the page for them.
Yes, you could obscure the URL (make it some mostly unguessable string of characters), but it's not clear what problem that is solving. The user themselves won't be able to remember it or type it so it would probably have to be a link in a web page and if it's a link in an unauthenticated web page, then anyone can get to it - thus defeating the purpose.
There are cases where temporary links (often done for privileged downloads) such as what you mention /user/PdfgdfJFDGTfrfgdsf are sent via an authenticated channel (either an authenticated webpage or sent to an email address known to belong to an authenticated user) and these links contain some unique and hard to guess code. The user can then click on that link (in authenticated webpage or in email) and access that resource without further authentication. In that case, the knowledge of the code in the URL is serving as a form of proof of authentication. Because URLs may be logged in service providers or corporate infrastructure and thus not remain entirely private, this technique has its limitations and is typically only used for short term (download this resource in the next 10 minutes) type of uses, not a long term substitute for authentication and not used for things that demand real security. You don't explain enough of your use case to know whether this is practical for your situation or not.
The user doesn't need to be authenticated in order to execute this code. However I don't want that anybody can execute this request with a user id of someone else. Because he could see data he's not supposed to see.
That's an inconsistent statement. You say "user doesn't need to be authenticated in order to execute this code" and then you say "I don't want that anybody can execute this request with a user id of someone else.". You can't have both. The user is either required to prove authorization or they aren't. Pick one. It can't be both.
you can use jwt for this and a auth middleware for this
upon decoding jwt token, you can implement logic to check if the decodedToken.user_id (given that you add user_id when encode token payload) is equal to the :idUser in route (or any kind of logic you want) there.

Check user permissions in RESTful API

I'm developing a SaaS API with NodeJS, Express, MongoDB. It has implemented a JWT authentication/security methodology.
In my personal case, I have (for now) two collections: User and Client.
You can see the fields that each collection has (for defining purposes). So in terms of endpoint design I'm using a trully restful approach so:
/api/users/{userId}/clients: to insert clients i.e.
This is exactly the point I'm bringing I want, that before posting a new client to check if the price plan allows the user to do that. In terms of logic:
function post(req,res){
// Check if the JWT user.id is the same of the endpoint request
if(req.user._id == req.params.id){
// Here I want to know which is the price plan and to count the Clients that the user has
}
}
In terms of my doubts I have thought in some hypothesis but I truly don't know which one is the best:
Do a query in the User collection get the price plan, do a query count on the Clients collection validate and then post the new Client.
Put the User's price plan information in the JWT, do a query count on the user's Clients collection validate and then post the new Client.
These are the two main possible solutions I thought about, but I have serious doubts security and performance wise of which one I should implement/follow.
Thank you in advance.
I have same doubts. Also if you put anything into your tokens, then when information change, you will have to reissue those tokens (will have to make user login and logout) or implement complex token update logic. Also application evolves: today you need price, tomorrow something else. Changing every time tokens of all users (using it as distributer storage by fact) is not a good idea probably. That's why it is better to keep JWT as short as possible.
Your question is more opinion based, but as my own opinion, I would definitely store in jwt only userId (+ meta information if needed). But not app specific things. Reading from database is the way to go.

PassportJS authentication and mongodb database collection best practices?

I am working in a project and actually the first time using nodejs, express and mongodb. For the authentication i am using passport.js which look pretty flexible and easy to integrate it.
I really like the idea of Serializing and Deserializing but my concern is about the user object which is always ON and can be used on every request.
My project involve subscriptions, user profile and maybe a small ticked system.
So my user schema it contains user credentials, user info like address, phone, email and also information about the subscription. Some of this information is embedded documents with in same schema. It seems weird that all this info is always ready even i do not needed, even the bcrypt password is always on the request call.
My question is, do you think is best practice to separate the user credentials from the user object and play with relationships soi can call the user info when i need it with normal controller model way?
Thanks in advance
if you are referring to sessions you should really only be sending a small piece of data with the request such as a user id. The entire user document should not be going across with every request.
It's common practice to separate user credentials from the rest of the user data, because the credentials need to be stored in a very secure manner - so much so that it dictates different infrastructure.
I work at Stormpath and we provide this as a service. We store the password for you, with very high levels of encryption. We have a great integration for Express, you check it out here:
https://github.com/stormpath/stormpath-express

Resources