Now to take a closer look at API routes
and how we can protect those,
I will take this change password example.
This clearly is an operation that should be restricted.
Not every user should be allowed to change a password.
It only makes sense for authenticated users
and hence, I will add a new API route
and we can add it in the API auth folder,
but we could also add it somewhere else,
and to show that it does not have to be in the auth folder,
I will create another folder, in the pages API folder,
and that will be the user folder,
but you could add it in auth, as well,
and in there, I'll add the change-password.js file
because I want to create an API route,
which can be reached by sending a request
to /api/user/change-password,
that's reaching this file then.
Now in this file, we're not going to use NextAuth,
at least not as we did it
in this square bracket nextauth file.
Instead, we're going to create our own API route,
just as we learned it in this course.
So I'll create a handler function here,
which gets a request and a response,
and I'll then export this as a default here,
and now in this handler function,
we want to extract the old and new password,
which the user entered here.
We want to verify that the request is coming
from an authenticated user
and deny for reaction, if it's not.
We want to get the email address
of that authenticated user then,
and then we want to look into the database,
see if we find that user there,
see if the old password that was entered matches
the current password in the database,
and if that's the case,
we want to replace that old password with the new password.
So that's what we're now going to do
over the next minutes.
Now for that, in the handler function,
the change-password.js file here,
let's first of all, check if the incoming request
has the right method, and for changing the password,
a POST, or a PUT, or a PATCH request makes sense.
These are the three kinds of requests that imply
that resources on the server should be created or changed,
and you can argue whether changing a password
is creating a new resource, a new password,
or changing an existing resource and existing user,
and I will go for the latter argument,
and I want to say that I only want to continue here,
if the incoming request has a method of PATCH.
So if it's not PATCH, then we will just return
and not continue at all.
We will only continue for PATCH requests,
which of course means that in the front-end,
so in our client-side code, we'll have to make sure
that we do send a PATCH request to this API route later.
So that's check number one.
Check number two, is whether that request is coming
from an authenticated user or not,
and if it's not, we also want to return with an error,
and for this, we can again use
this getSession function here,
which we already used on the profile page.
There we are already using it in server-side code,
inside of getServerSideProps.
So we already see that it runs on the server,
as well as on the client,
and that of course means that we can again,
use it in our API route, which also is server-side code.
So therefore, in the change-password.js file,
I will again, import getSession from next-auth/client.
The /client can be confusing, but this does work
on the server, as well, as we saw,
and then we want to check if we do get a session.
For this we can store a session a constant,
and we get it by calling getSession,
and then as you learned, on the server-side,
we can pass in an object where we set the req key
to the request we're getting here.
GetSession needs that incoming request,
because it will then look into that request,
see if a session token cookie is part of the request.
If it is, it will validate and extract that data
from that cookie, and if that all then makes sense,
it will give us the session object.
Now, getSession actually returns a promise,
and to use async await,
I'll turn this into a async function
and I'll wait here.
So now we get our session,
or we don't get one if the user is not authenticated,
and therefore, we can check if not session,
if that's undefined,
which means the request is not authenticated,
and in that case, we also want to return
and here, we may be also want to send back a response.
We could send one back in this first if check as well,
a special response,
but I don't care about that here, but here,
I actually do want to send back a response
with a status code of 401,
which basically is the standard status code
for saying that authentication is missing,
and then possibly some extra data attached,
like a message of not authenticated,
but of course, it's up to you,
which kind of data, if any, you want to send back.
So that's now another important check,
and that is the key check of this module,
of this course module,
because this line here or this block of code,
that's the code where we validate whether a request
is authenticated or not.
This is the code with which we protect our API route
against unauthenticated access,
and every API route that does something
that should only be allowed to authenticated users,
needs code like this.
Everything else we're going to write in this API route
is not directly related to authentication.
Yes, we're going to change the password of a user,
and that of course, has something to do with authentication,
but on the other hand, changing a password is really not
that different from creating a product.
We're just changing some data in the database in the end.