Controller uses Dto file to create a new user, does the Model it self needs to include restrictions?
Hello! I have a model of "User" which include User basic attributes, I also added restrictions like password length (max, min and errors).
When the controller creates a new user, it uses a Dto file (which obviously has less attributes than the Model it self) and then mapping it into the model which stores it into the database.
Does the Model needs the restrictions or the Dto is enough for restrictions?
For example: (picture)

47 Replies
It depends on your architecture
Normally it would be really nice to control all you invariants very close to domain model itself (on very bottom layer of application). In this case you can guarantee that any upper layer would follow your restrictions. And then this restrictions also propagates to upper layers up to representation layers (aka WEB API in most cases)
If your application is not very complex, just do the easiest way. If you have very complex logic and you need STRICTLY CONTROL that only valid models exists - then use what I said above
and normally DTOs don't have any restrictions. They purpose to be
data transfer objects
so I think you mean not DTO's but any other architecture layer modelsI was following a video where he used Dto in order to create\read an object without the need of the irrelevant attributes like id, etc...
He didn't put restrictions in the Dto layer but I did, because it seems like the Model it self doesn't control the restrictions when I use Dto, and then use the Swagger for the Controller methods.
For example:
When I put Dto to create a new User for my database and I don't put restriction like "Minimum password length = 8" and I put this restriction only in the Model it self, and then I go to the Swagger and use the "Register" method in the Controller, it doesn't stop me from creating an object with password of length less than 8.
It seems like the restrictions don't exist.
In the picutre it is the Controller method: I know there are better ways to create Controller (someone gave me 2 articles to read about it, I'll do it after I'm done)

I see, but that means it is no longer DTO, bcs DTO only responsible for transfering data - not holding invariants
The model represents the database row, so it should have whatever restrictions you want to be on the database
Werid, it didn't work for me, maybe I did something wrong.
I'll update in 5 minutes
Thank you very much for the help umtil this moment
There are dozen books and articles of domain driven development with clean architecture. You can take a look at that to deeply understand things
The PasswordHash with restriction belongs to the Model
The PasswordHash without the restrictions belongs to the Dto
I've created a user with password of length 2 and yet it lets me



I'm in race against time, I'm doing this as a degree project, so I don't have much time to freely check many resources (eventhough I want honestly)
I am curious, why is your API have
PasswordHash
as parameter? And why it is query? It is not the way it should be
then do the easiest solution for you. There is no need to be worry unless you will have a problems with it's support
I also suggest you to move all /Register
endpoint data inside a body - not a query string
especially the passwordI watched a video where the instructor used normal "password" attribute but then chatGPT recomended to convert it into hash in order to make it more secured.
I have no idea what this (query) is honestly, I'm just flowing with it :nervousowo:
Look
Storing as hash in the database — yes
Sending hash from the client — why
You are creating an API for external usage. Hashing the password is a logic of storing a password in secure manier in DB. And there is no any point to the external user to know the hash. Hash only exist for your infrastructure inside ur app
external client should "know" as less as possible I would say
I'm confused
But until this moment when I used the Swagger I totally put a normal password like "11" and then in the Database I saw it got converted into this weird long hash code.
Am I wrong?
I'm sorry, I'm kind of beginner so I have weird questions
When user registers, they send a plaintext password, the backend hashes it, and stores it in the database.
When user logs in, they send a plaintext password and login/email, the backend finds the password hash by the login/email and checks if it checks out
The user does not send or receive the hash at any point
Yes I understand this logic, makes sense
So wait, the problem is my Dto attribute name? That I named is PasswordHash instead of password?
That would be the source of confusion here, yes
It used to be "Password" I changed it because I thought it was wrong 😂 my bad
Is that all with the password hash problem? or am I missing more?
And thank you very much
Far as I can tell, yeah
Not sure if
BCrypt.HashPassword()
salts the password before hashing
That could be another issue if it doesn'tWhat do you mean by "salts"?
If one person has
hunter12
for password, and another has hunter12
for password, that will provide the same hash
That's why passwords are salted before hashing, for example into 12345-hunter12
and 67890-hunter12
Those will provide different hashesohh cool
I think that what happens, I can check
The flow you need is getting the data from a client:
then you need a function to create a hash:
after that create a database user representation:
and insert it to DB
and before storing in DB, you should create a model of user:
it is very important to create
UserData
from UserModel
- not from RegisterRequestData
!!!!!!!
the model can be only exist if it's valid
and you can check the password length before creating an instance of UserModel
1. get the data from a user
2. validate data
3. create instance of model
4. do some extra logic with instance of model
5. create an instance of database model
6. attach it to database
and if you have multiple layers, you can define your checks in eachOmg thank you very much, I appreciate it ❤️
Why is that method important?
"public bool CheckPasswordHash"
I don't udnerstand its purpose
What that means "if hash of rawPassword == passwordHash"?
If the user puts a plaintext password like "11" and it converts it into hashType then why do we need to check the hashType password? what exactly it validates?
Hash function is one way function. That means having password
111
you can get it's hash like 6216f8a75fd5bb3d5f22b6f9958cdede3fc086c2
(sha1 btw). But by having the hash you can not get the password back. If you database was compromised, hackers would get only hashes and not passwords. If your users use same password for all websites hackers won't get theirs google accounts
So in this case how can we validate if user inputs the password and it is his password? So we MUST need a function to validate if 111
== 6216f8a75fd5bb3d5f22b6f9958cdede3fc086c2
somehow
Validate could be like
1. get the password hash from database for this specific user
2. generate a temp hash with same hash function from user input
3. check if both hashes are match each other
In the realty it's a bit more complicated. And we use HMAC for tokens to give them to users and validate as well
and another thing, don't use MD5 / SHA-1 or even SHA-256 for passwords. They are no longer secure. You can brute force them. I suggest to take a look at Argon2not even SHA-256?
1 things I'm confused with
When your usera gives a password like "111" and you get something like "6216f8a75fd5bb3d5f22b6f9958cdede3fc086c2"
And then a user wants to login with his current password, so he inserts "111", so what you want to do is:
1. get the password hash from database for this specific user -> (Which means we go to the account inside the database, gets the hash version from there)
2. generate a temp hash with same hash function from user input -> You put the given plaintext the guy gave which was "111" again and generates it into Hash,
The hash function will generate the same hash password again? like "6216f8a75fd5bb3d5f22b6f9958cdede3fc086c2"?
So the passwords are identical and the user can login?
But if the hashes are identical, then they will be generated the same also in other websites. 111 will be equal to ""6216f8a75fd5bb3d5f22b6f9958cdede3fc086c2"" no?
i dont get it
hashes are designed for "same input, same output", so yes, if someone input "111" and get "xyz" then later they "111" they'll get "xyz"
always right?
always, it's an unchanging mathematic algorithm
you cant turn hash back into password (you technically can but no one practically done that)
But then 2 users who give the same plaintext password will have the same hash-code no?
yeap, sha-256 is very easy to compute. Argon2 makes it slower which means it brute forces much longer. It has time cost, memory cost and parallelism
same input, same output
perfect
next time use RSA-4096 to encrypt ur password instead of hash comparison :kekw:
@kurumi
Thank you so much for the long explanations, you are amazing
@ZZZZZZZZZZZZZZZZZZZZZZZZZ
Thank you for the long help
@EntityRef<Ashy>
thank you for the last explanation, helped much
I think I got it
you got it
good luck
$close makes sense?
If you have no further questions, please use /close to mark the forum thread as answered
thank you very much
makes sense
If I type /close the conversation won't disappear right?
idk :kekw:
my first time helping
it will just marked as resolved
perfect
you can extend it after, edit or ofc view
thanks again ❤️