We've got a big problem, a big security flaw
in our current signup process.
We've got a couple of problems, actually.
One problem, for example,
also is that we don't validate the user input.
I'll come back to that later, and what I mean by that.
But the even bigger problem right now is
that we're storing the password
as plain text in that database.
So here in the database,
I have the password just as I entered it as a user
on the website a couple of seconds ago.
And why is that a problem?
It is a problem because if this database
should ever get compromised,
if we got an employee who decides to do bad things
and wants to extract some user passwords,
or if we're getting hacked,
which can happen, even if we're trying all to prevent it.
But if we're getting hacked
and someone gets access to this database,
he or she will be able to get all the user data
with all the raw passwords.
And we have all read about data breaches like this
in the news.
Where some company did store passwords as plain text,
as we are doing it here right now.
And when that database then got compromised,
and the data got lost or stolen,
then all that data could just be used like this
by criminals.
And since users, for example,
tend to use the same password on multiple pages,
no matter if that is recommended or not, it's the reality.
Since users use the same password on multiple pages,
if I can extract your password from this page,
I can also try this email password combination
on other pages, like your online banking account,
or your Amazon account.
And that's all not good.
So therefore, what you should do
if you're storing user credentials in a database
is you should always hash the password.
Hashing the password simply means that you change it.
You don't change it randomly,
but you use some algorithm for changing it,
and you change it as such that it can't be converted back.
This might sound strange because in the future,
you also need to be able to verify the password.
But when you use a hashing algorithm,
that algorithm will be able to compare an unhashed password
to a hashed password,
and find out if the unhashed password
would lead to the same hash
without reverting the hash.
Might sound all very cryptic.
But in the end, it is a way of ensuring
that you can store a password
in an obscured way in a database,
and in a way that can't be decoded,
and still be able to verify the password in the future.
And therefore, that is something we should do here.
We should hash the password
before we store it in the database.
Hence for the moment here, I will just delete my user here,
and delete the user with the email test@test.com
because I don't want a user with that password here.
And we'll implement this password hashing
in our website now.
Now, hashing passwords is a complex task
because you need an algorithm that converts passwords
such that they can't be decoded.
A very popular third party package
that does this for us
is the becrypt.js package.
You can just search for it
to find its official documentation here.
Here you'll learn how you can use it and how it works.
And this package will ensure that we can convert strings,
like passwords, into undecodable, hashed strings
which look random to humans,
but which follow a certain pattern,
but which can't be decoded back to the original password.
So let's stop our server here,
and simply install becrypt.js
by running npm install becryptjs.
And then once this package is installed,
we can start our server again.
And in demo.js at the very top,
where we have all our imports,
we now want to import becrypt by requiring
becryptjs like this.
And now we can use this third party library
to hash our passwords.
So now here
in our signup post route,
instead of storing the password like this,
we will, first of all,
create a hashed password here by using bcrypt.
And there we can call the hash method,
which does what the name implies.
It takes a string like our password,
and then creates a hash.
So such an obscured string based on it.
For this, we pass our entered password
as a first parameter value.
And then the second value is a number that
in the end determines how strong the hashing is.
If it's not strong enough, it could be decoded,
but a value of 12 here
should actually produce a fairly secure password,
which can't be decoded.
So where you can't infer the original password.
Now, hash actually returns a promise.
So here we also have to await this.
So then at some point, we got this hashed password,
and now it's this hashed password,
which we should store in the database
instead of the unhashed password.
So now here we can save this,
and with that, if we now go back and create a user again.
Like this.
We still are redirected.
We still get no error here.
But if I now have a look at all my users again here
in my database, we now see that for this user,
now we don't store the original password,
which was entered,
but this string here,
which clearly gives us no clues about the original passwords
and which, as I mentioned before,
can't be decoded back to the original password.
Still, we'll be able to verify the entered password
in the future.
That's the great thing about it.
But now with that,
if this database ever gets compromised or hacked,
you won't be able to just use that password
to log into other websites,
because this isn't the original password.
It's a hash, which you can't convert back
to the original password.
And therefore, this is a huge security step up,
which you absolutely should have in your websites.