Now before we continue with
the authentication logic and logging users in,
we got a couple of improvements to make about the
signup process.
Of course, we will need to validate
the incoming data and ensure that, for example,
the email and confirm email that these two values match,
but we also should improve the security of our website by
protecting against CSRF attacks.
I covered those earlier,
in the Dedicated Security Section of this course,
and the idea behind CSRF attacks is that
attackers can assume the identity of our users,
which will be especially a problem
once our users are signed up and in.
So at the moment, that's not possible
because we're not really logging users in yet,
but I already want to start implementing security measures
against CSRF attacks.
And last, but definitely not least things can go wrong.
We might fail with saving user data to the database.
This could throw an error,
if the underlying methods that talk to the database
are throwing errors.
So therefore, of course, I also want to add error handling.
These are the different things that should be added,
and I'll start by adding CSRF protection.
For this I'll use a third-party package
because coming up with my own measures is pretty error prone
and a very popular note express package
for protecting against CSRF attacks is to CSurf package.
Which is the package I'll install here.
With CSurf installed, we can restart our server here.
Back in app.js we want to activate this package.
This is done by first of all, importing it there
by requiring CSurf like this.
And then we activated as a middleware.
The exact position doesn't matter,
but you want to do that before a request to reaches your
routes. So I will actually do that here,
use CSurf or the CSRF package.
And this is actually all is a function which we have to
execute. And then it's this executed function,
which recurs the actual middleware that will be registered
because we can configure it this middleware.
But the default settings will do the trick for us here
and therefore we don't need to do anything else.
Now we will have that CSRF protection,
and that simply means that all incoming requests,
which are not Get requests,
now needs to have a CSRF token attached.
This is what this middleware will check for.
And any requests that are not Get requests
that don't have a valid CSRF token
will be... denied; They won't be able to continue.
Therefore, we need to ensure that we add such a token to
all the forums we have on our page,
and to do this conveniently,
I will add my own custom middleware now.
Because I don't want to extract the token and use the token
manually in different parts of this page. Instead,
I want to use a feature built into express,
which allows me to set up a variable on my response
that I can then access in all my views
so that we don't have to pass the token
into all our views manually.
And I'll do this in my own custom middleware
so that I don't write the logic for setting this variable
in app.js, but I can instead keep this file relatively lean.
Hence we can add a middlewares folder.
And in there I'll add a 'CSRF- token.js' file.
And there we can add our own middleware
and a middleware is just a function in the end.
The function name is up to you, but I'll name it.
'addCsrfToken'
like this,
and this will receive a request and a response.
And the next value.
These are the three parameter values all
middlewares will receive because express we'll call
those middlewares for us.
And it will pass these three values into those
middleware functions.
And then we can work with these values here,
and I will work with all three of them in addCsrfTtoken
because on the response,
I'll use a feature supported by express,
which allows me to set variables
that are exposed to all views automatically
with help of the locals property.
And on locals, I can then add my own key value pairs
like token and the value of that custom property on locals
will be request dot CSRF token, which is a method I call.
This method is available
thanks to the CSRF middleware package
we added a couple of minutes ago.
So this generates a valid token.
This token is then saved in res.locals and locals is
available in all my views later on.
Now I just need to make sure
that once this middleware was executed,
the request for which it was executed
is able to reach the next middleware or route handler
in line, and that can be achieved by calling next
this third parameter value.
That's a function which, when executed, forwards the request
to the next middleware in line.
Now we just need to expose this custom middleware
by exporting it like this.
And then we can use it in app.js.
Here... I will...import it,
maybe here
the addCsrfToken middleware, as I will call it,
to make it very clear that this is a middleware.
And I will require it
by going to ./middlewares/csrf-token
which is the file we just worked in.
And then here, after using the CSRF package middleware,
I will use my own middleware here.
My own addCSRFtoken middleware I just imported.
It's important that we do this after
registering the package middleware
the CSRF package middleware,
because that is the middleware dead gives us this
CSRF token method,
which I am then using in my own middleware.
So we have to execute our custom middleware,
which relies on the existence of this method,
after the third party package middleware.
We don't need to execute addCSRFtoken middleware here,
because unlike the third party package function,
that is exposed here,
this already is the final middleware function,
and we don't want to execute that ourselves.
Instead, we want to make it available
to express, for express to execute it.
And now we can go to the signup.ejs file.
And in this forum, we now have to make sure that the token
is part of the forum submission.
So part of the data that's generated and sent along
with the request when the form is submitted.
And typically this is achieve by adding
a special type of input, a hidden input,
which is one of the built in types.
This is an input which is not visible to the user and which
is not meant for the user to be populated with data,
but which instead is already there
and sent along with the request.
Now this needs to have a special name
for which the CSRF package will look
and that's underscore CSRF
and the value then is set by us,
but it's not hard coded into the view. Instead it is
that token that's generated with help of the package,
that token, which I generate here.
Which is stored in a CSRF token property on that
locals field, which is provided by express.
So here we can use the EJS templating language
to output a value.
And the value I do want to output here, is locals
without rests in front of it, just locals,
and then our key name CSRF token.
And I will already copy that and also add it to login
EJS into that form, because we'll need that there as well.
With that we added CSRF protection,
and... if I reload this fails.
And this fails because CSurf package actually also needs
the session package. It needs a session to handle that
CSRF token. And at the moment we haven't added any session
support or a session functionality at all, to our site here.
Therefore at the moment, this will fail,
but that's no problem because we've got a couple of other
things to fix anyways, before we then we'll add sessions.
And before we then we'll evaluate the final result again,