Coding

Adding User Signup | Creating a REST API with Node.js

  • 00:00:02 welcome to this video let's continue
  • 00:00:04 building our restful service with no js'
  • 00:00:07 and in this video I want to start adding
  • 00:00:11 authentication so that we can ensure
  • 00:00:13 that certain resources on our server are
  • 00:00:16 only available to users who are logged
  • 00:00:19 in now of course one important question
  • 00:00:21 will be how we actually implement
  • 00:00:24 authentication in a restful service
  • 00:00:26 because it's different to your normal
  • 00:00:29 node.js application you might have
  • 00:00:31 written and I'll have a look at this and
  • 00:00:33 then of course actually implement it in
  • 00:00:35 our project in this video so let's start
  • 00:00:41 let's start by first understanding how
  • 00:00:44 authentication works in a restful
  • 00:00:46 service as we are building it so we get
  • 00:00:48 a client and a server and remember a
  • 00:00:51 client is for example your web app your
  • 00:00:55 building so the front and facing the
  • 00:00:57 client facing web app which you might
  • 00:00:59 write with a framework like angular
  • 00:01:01 react or do or with an vanilla
  • 00:01:03 JavaScript or any other client could be
  • 00:01:06 a mobile app that connects to a back-end
  • 00:01:08 to also have a data layer to be able to
  • 00:01:10 store data and fetch data these are your
  • 00:01:12 clients I talked about them earlier in
  • 00:01:14 this series so make sure to go through
  • 00:01:16 all the earlier videos too so that's our
  • 00:01:19 client that's our server now we want to
  • 00:01:21 log in and for that the client is going
  • 00:01:23 to send some off data to the server with
  • 00:01:25 off data I mean email address and
  • 00:01:28 password of a user if we have a typical
  • 00:01:30 email and password of indication flow on
  • 00:01:33 the server we then if we're signing up
  • 00:01:35 we can then store this data in the
  • 00:01:37 database by hashing the password and
  • 00:01:40 storing it and so on or if the user is
  • 00:01:42 logging in because you already did sign
  • 00:01:44 up in the past then we would simply
  • 00:01:47 check these values on the server so we
  • 00:01:49 would verify if the user who's sending
  • 00:01:52 us this data actually has a valid
  • 00:01:54 account for this given data on our page
  • 00:01:57 so this is what we do on the server and
  • 00:01:59 then we return something in a normal
  • 00:02:02 node app that would be a session but in
  • 00:02:05 a restful service it can't be a session
  • 00:02:07 because remember restful services are
  • 00:02:10 stateless they don't save any
  • 00:02:13 information about connected clients at
  • 00:02:15 least not like this we don't care about
  • 00:02:18 whether a mobile app or a web app
  • 00:02:20 connected therefore we don't use
  • 00:02:22 sessions and we also can't use sessions
  • 00:02:25 because some clients might not even
  • 00:02:28 support the idea behind sessions say a
  • 00:02:31 mobile app might not support a session
  • 00:02:33 or for example if we connect to our API
  • 00:02:36 from an aviary I so from an average
  • 00:02:39 which runs on a server then also
  • 00:02:42 sessions wouldn't make any sense so
  • 00:02:45 we're not connecting through a session
  • 00:02:47 or we're not building such a session
  • 00:02:49 instead what we do is we will actually
  • 00:02:54 returned a token now a token essentially
  • 00:02:58 will be some object some piece of data
  • 00:03:01 that will actually contain some
  • 00:03:05 signature so that we can verify on the
  • 00:03:07 server if it's a Bella token so that we
  • 00:03:09 can't fiddle around with it on the
  • 00:03:11 client and some information about the
  • 00:03:13 locked and user and this token can then
  • 00:03:15 be stored by our client and can be used
  • 00:03:19 to be attached to future requests so
  • 00:03:23 that whenever we in the future try to
  • 00:03:25 access something on the server which we
  • 00:03:27 want to protect we attach that token
  • 00:03:30 which we received from the server we can
  • 00:03:33 then verify this token on the server
  • 00:03:35 because of the signature which is
  • 00:03:36 attached to the token so that we can see
  • 00:03:38 that it still is – token we issued and
  • 00:03:40 it hasn't been messed around with and
  • 00:03:42 once we got that verified we know you
  • 00:03:46 got a token the token is valid so you
  • 00:03:48 may access this resource and this is how
  • 00:03:50 how authentication works here we work
  • 00:03:53 with these tokens to not store the
  • 00:03:56 information whoever you are allowed to
  • 00:03:58 access something or not on the server
  • 00:03:59 but on the client but in a way that we
  • 00:04:02 can always check if it's valid on the
  • 00:04:06 server that's of course important
  • 00:04:07 otherwise anyone could send us a token
  • 00:04:09 and if we just check if a token is there
  • 00:04:11 then this would not be very secure but
  • 00:04:14 by being able to verify this token well
  • 00:04:16 it is actually pretty secure let's have
  • 00:04:19 a closer look at this token though so
  • 00:04:21 this token is called a JSON web token
  • 00:04:24 typically or typically we use this
  • 00:04:26 format to be precise because it simply
  • 00:04:28 is just adjacent data object in the end
  • 00:04:31 where we can add some information like
  • 00:04:34 the idea of the user or the email
  • 00:04:36 address of the user who is signed in and
  • 00:04:38 some signature so these two pieces are
  • 00:04:41 important it also contains data about
  • 00:04:43 when the token is going to be expired
  • 00:04:45 and the issuer of the token overall all
  • 00:04:49 this data which we put together into a
  • 00:04:51 token makes up this JSON web token which
  • 00:04:55 we return to the client now the
  • 00:04:57 important part is what I mentioned
  • 00:04:59 earlier we can verify this signature and
  • 00:05:02 therefore the validity of the token on
  • 00:05:04 the server and if we may
  • 00:05:07 add something to the token or try to
  • 00:05:09 fake the token we could find out that it
  • 00:05:12 is not a valid token on the server
  • 00:05:14 because we use a private public key
  • 00:05:17 combination and only the server knows
  • 00:05:18 the private key so only the server has
  • 00:05:21 both keys it needs to in the end
  • 00:05:23 validate this token one important note
  • 00:05:26 though the token is not encrypted so
  • 00:05:28 once we've got it on the client we can
  • 00:05:30 actually have a look at it we can
  • 00:05:33 extract the data from it but as I said
  • 00:05:36 if we try to change it well that doesn't
  • 00:05:39 do anything
  • 00:05:39 we can still verify it on the backend so
  • 00:05:43 this is how this token works and what we
  • 00:05:46 do with it or how it is structured now
  • 00:05:49 thankfully we don't have to build a
  • 00:05:51 token on our own if you want to learn
  • 00:05:53 more about the token though you can you
  • 00:05:55 can simply dive into the video
  • 00:05:58 description where you will find more
  • 00:05:59 information about the token but I'd say
  • 00:06:02 let's stick to this right now
  • 00:06:04 and let's actually implement
  • 00:06:06 authentication with JSON web tokens in
  • 00:06:09 our restful service so let's add
  • 00:06:12 authentication and to add authentication
  • 00:06:15 we need users right so I'll first of all
  • 00:06:18 create a new model and I'll name it user
  • 00:06:21 J s because here I wanted to find how a
  • 00:06:23 user should look like in my app I'll
  • 00:06:25 then copy the order model let's say just
  • 00:06:28 because I'm going to use the general
  • 00:06:29 same layout I'll rename order scheme add
  • 00:06:32 user schema though and I'll rename my
  • 00:06:35 model from order to user now the fields
  • 00:06:39 here will also vary of course we got our
  • 00:06:42 ID but I don't have product and quantity
  • 00:06:45 here instead here I want to have my
  • 00:06:48 email let's say and there I'll add an
  • 00:06:51 object which is of type strings or which
  • 00:06:54 says that it should be of type string
  • 00:06:55 and also that it's required so let's set
  • 00:06:58 this to true and I want to have a
  • 00:07:00 password of course password also will be
  • 00:07:03 a string and also is required so these
  • 00:07:06 two fields need to be given or need to
  • 00:07:08 be there if we create a new user model
  • 00:07:11 now we can revisit this later to also
  • 00:07:14 add connections to products or orders
  • 00:07:16 but for now let's keep it simple and
  • 00:07:18 let's focus on the authentication
  • 00:07:20 so this is how a user should look like
  • 00:07:23 now I also need routes for the user so
  • 00:07:25 add my user dot JS file here in the
  • 00:07:28 routes folder and I'm going to set up
  • 00:07:32 the routes file file in the same way I
  • 00:07:34 did for the other routes so I'm going to
  • 00:07:36 copy these imports from Express router
  • 00:07:39 and Mongoose and put it into my user J's
  • 00:07:41 file and then at the very bottom of the
  • 00:07:43 file I'm going to export my router with
  • 00:07:46 the module exports syntax now in between
  • 00:07:48 will create their user related routes
  • 00:07:52 and for now I want two routes sign up
  • 00:07:55 and sign in you might wonder what about
  • 00:07:58 logout well since we don't store
  • 00:08:00 information about the user on the server
  • 00:08:03 we don't store the information wherever
  • 00:08:05 the user is locked in or not we can't
  • 00:08:07 lock the user out what would we do we
  • 00:08:09 there is nothing to delete there is no
  • 00:08:11 session we need to clear or anything
  • 00:08:13 like that so we don't need a logout
  • 00:08:14 route so let's create our first route
  • 00:08:18 then and that should be a post route to
  • 00:08:20 create a new user and I'll simply name
  • 00:08:23 is slash signup that will be my path
  • 00:08:26 overall the path will be user slash
  • 00:08:29 signup but I'll load these routes just
  • 00:08:32 as I load the other routes from within
  • 00:08:34 app chess by importing it here and then
  • 00:08:36 using certain prefix and then pointing
  • 00:08:40 to the routes file but that will be the
  • 00:08:42 next step now for now let's simply
  • 00:08:43 create our signup route here of course
  • 00:08:46 we create the routes just as we did in
  • 00:08:48 the our files so I'll add a second
  • 00:08:50 argument where we get the request the
  • 00:08:52 response object and this next function
  • 00:08:54 we could execute if we were building a
  • 00:08:56 normal middle where and then here now
  • 00:08:59 the goal is to create a new user now
  • 00:09:02 let's see how we can do this
  • 00:09:03 first of all I'll import the user model
  • 00:09:07 so I'll trade a user constant here and I
  • 00:09:10 will require it from my models folder
  • 00:09:12 and there from the user file now what we
  • 00:09:15 can do is we can create a new user by
  • 00:09:18 creating a new constable case user and
  • 00:09:20 then this will be a new user now this is
  • 00:09:24 just as we for example create a new
  • 00:09:26 product to write there we create a new
  • 00:09:29 product using our product mongoose model
  • 00:09:31 now to the user we can pass a
  • 00:09:34 javascript object and now there are a
  • 00:09:36 couple of things we needed to create
  • 00:09:37 also keep this in mind we created an ID
  • 00:09:40 and then we assign the different values
  • 00:09:43 so I'll copy the ID value from the
  • 00:09:45 products route because we create the ID
  • 00:09:47 in exactly the same way with the
  • 00:09:49 Mongoose types object ID helper method
  • 00:09:51 here but then remember we had two fields
  • 00:09:55 here email and password so what I'll do
  • 00:09:58 is I'll add email and password here
  • 00:10:02 now why of course need to be populated
  • 00:10:05 and I will assume that we will get these
  • 00:10:08 fields from the incoming request so we
  • 00:10:11 can say the email is request body email
  • 00:10:14 and then we can also say the password is
  • 00:10:17 request body password now this pattern
  • 00:10:22 or doing it like this has one major
  • 00:10:25 extremely bad security flaw do you see
  • 00:10:29 which one which flaw I mean well we
  • 00:10:33 store the raw password in the database
  • 00:10:36 now let's consider or let's assume that
  • 00:10:39 we get the password via HTTP that in the
  • 00:10:43 end we host our app why I HTTP still
  • 00:10:47 still at that case we would get our
  • 00:10:52 password through an encrypted and
  • 00:10:54 protected connection but we will store
  • 00:10:57 it in plain text form in the database
  • 00:11:00 and if anyone ever gets access to our
  • 00:11:04 database be that an employee or an
  • 00:11:07 attacker of our website then all our
  • 00:11:09 user passwords are going to be readable
  • 00:11:12 just like that we don't want that so we
  • 00:11:15 need to encrypt our password we need to
  • 00:11:18 hash it and for that we'll use a package
  • 00:11:21 we'll use node be tripped Jas now github
  • 00:11:27 link can be found in the video
  • 00:11:28 description and yentas is just a package
  • 00:11:30 that will hash our password and hash it
  • 00:11:32 in a secure way that also can't be
  • 00:11:36 unhatched so to say or can't be
  • 00:11:38 translated by using dictionary tables
  • 00:11:41 I'll come back to how exactly this works
  • 00:11:42 in a second so here on this page you see
  • 00:11:45 the installation instructions on how to
  • 00:11:47 use it
  • 00:11:48 I'll copy the install command here and
  • 00:11:50 shut down my server and run npm install
  • 00:11:53 bcrypt I'll also add – – safe to add an
  • 00:11:56 entry to package.json this will now
  • 00:11:58 install this hashing library which I
  • 00:12:01 will use to do the hashing for me now
  • 00:12:04 we'll take a couple of seconds you might
  • 00:12:06 see some errors in between us I do here
  • 00:12:08 but it should be able to recover from
  • 00:12:10 these and fall back and finish without
  • 00:12:12 an error in the end then we can restart
  • 00:12:15 a server with NPM start now we see how
  • 00:12:18 to use it here and I will simply use
  • 00:12:21 that hash method here so this is how we
  • 00:12:25 do hash our passwords I will import it
  • 00:12:28 first of all import decrypt by requiring
  • 00:12:31 be tripped like this and then the
  • 00:12:35 password should be stored using this be
  • 00:12:38 crypt library and there the hash method
  • 00:12:41 now the first field here is request body
  • 00:12:44 email so that will be the password I
  • 00:12:47 want to hash in plain text form and then
  • 00:12:51 we have these salt rounds now what the
  • 00:12:54 salting mean here well the following is
  • 00:12:56 the case if we hash a password
  • 00:12:58 theoretically that is safe because you
  • 00:13:01 can't reverse a hash you can't translate
  • 00:13:04 a hash to the plaintext value it's a
  • 00:13:06 one-way operation and if you wonder how
  • 00:13:08 we then are able to verify if a password
  • 00:13:11 the user enters on sign-in is the same
  • 00:13:13 password we store the database I'll come
  • 00:13:15 back to this so in general it's non
  • 00:13:18 reversible but if you get this hash in
  • 00:13:23 the end which is just a random string
  • 00:13:25 and you would Google that hash chances
  • 00:13:27 are high you would find a translation to
  • 00:13:30 your plaintext password why because
  • 00:13:32 every plaintext string has a clear
  • 00:13:35 unique hashed version of it with the
  • 00:13:38 hashing algorithm getting used here and
  • 00:13:40 that means that so-called dictionary
  • 00:13:42 tables exist these dictionary tables are
  • 00:13:44 in the end just what they sound like
  • 00:13:46 we have plaintext values and the hash
  • 00:13:49 value for it so if your user has a very
  • 00:13:52 elaborate password of course no
  • 00:13:54 translation might existence actually a
  • 00:13:56 dictionary table but if your user uses
  • 00:13:58 something like ice cream chances are
  • 00:14:01 this translation does exist so if anyone
  • 00:14:04 gets access to your database they might
  • 00:14:06 still be able to get the plain text
  • 00:14:08 password from such a dictionary table
  • 00:14:10 the idea behind salting is that we add
  • 00:14:14 random strings cue that plaintext
  • 00:14:17 password before we hash it and then the
  • 00:14:20 strings that were added are also stored
  • 00:14:22 in the hash by doing it like this
  • 00:14:25 googling the hash won't lead to the
  • 00:14:28 plain text version of the password
  • 00:14:30 simply because the plain text version
  • 00:14:32 contains a random string and we don't
  • 00:14:35 have hashing tables dictionary tables
  • 00:14:38 for all kinds of random strings and that
  • 00:14:41 is what salting does and here you
  • 00:14:42 defined a number of salting rounds 10 is
  • 00:14:45 considered safe and with that we make
  • 00:14:47 sure that our passwords can't be looked
  • 00:14:49 up in dictionary tables and then we add
  • 00:14:52 a callback here this is a function where
  • 00:14:55 we as you can see documentation ebrill
  • 00:14:58 get an error or we get the hashed
  • 00:15:00 password so we have these two arguments
  • 00:15:02 and then we can check if we got an error
  • 00:15:05 here then we want to return a response
  • 00:15:07 where we send status code 500 and a JSON
  • 00:15:11 object where we maybe set an error
  • 00:15:14 object which contains our error so then
  • 00:15:18 we simply know okay this failed we don't
  • 00:15:21 have a password we couldn't store it in
  • 00:15:23 yet we couldn't safely hash it otherwise
  • 00:15:27 if you got no error then we have a hash
  • 00:15:29 password and this can now be stored in
  • 00:15:31 the parent in the database so what we
  • 00:15:34 need to do actually is change our code
  • 00:15:37 we don't assign this to password because
  • 00:15:40 it's no synchronous operation instead
  • 00:15:43 here this bcrypt
  • 00:15:44 operation is what we execute first and
  • 00:15:47 only if we make it into the else case
  • 00:15:50 only in this case we'll create a new
  • 00:15:52 user but then in the Al's case we got a
  • 00:15:55 password value and that will be the hash
  • 00:15:58 so this is how we now can generate or
  • 00:16:02 create a user with a hash password now
  • 00:16:05 if we
  • 00:16:08 half the user here then we can call
  • 00:16:10 users safe to save the user in the
  • 00:16:13 database and then we can again chain
  • 00:16:16 then here so just like we did for
  • 00:16:20 products but we also have then and catch
  • 00:16:23 too well do something with errors or
  • 00:16:27 with success cases so if we are
  • 00:16:30 successful we get back a result and
  • 00:16:32 there we probably want to return a
  • 00:16:34 response where we will be don't need to
  • 00:16:37 return even can just say response status
  • 00:16:43 web status 201 because we created a
  • 00:16:46 resource and then Jason where we could
  • 00:16:48 have a message where we say user create
  • 00:16:52 it something like that and we can also
  • 00:16:56 catch any errors of course and in such a
  • 00:16:59 error case we can do what we always did
  • 00:17:01 we can simply maybe log it to the
  • 00:17:03 console and return it so like this and
  • 00:17:06 let's also log our user in the result in
  • 00:17:10 the success case to the console so that
  • 00:17:12 we can see what was created here and
  • 00:17:15 with that if we save all of that we got
  • 00:17:17 our user creation to sign up route now
  • 00:17:20 let's test it and for that I'll go to my
  • 00:17:23 app J's file and in there I'll first of
  • 00:17:26 all imported so I'll import user routes
  • 00:17:30 by requiring dot slash
  • 00:17:36 API routes user so just like I do it for
  • 00:17:40 Diablo routes and then I'll go down
  • 00:17:42 there and also forward any requests
  • 00:17:46 going to slash user slash something to
  • 00:17:49 my user routes with that setup we should
  • 00:17:53 be able to reach that route with a post
  • 00:17:54 request now let's try it out in postman
  • 00:17:56 so here I am in postman I prepared my
  • 00:17:59 request post request to slash user slash
  • 00:18:01 sign up now I need to attach a body
  • 00:18:04 which is now not form data but a raw
  • 00:18:06 body of type Jason let's create such a
  • 00:18:10 Jason body and if you have a look at our
  • 00:18:12 route then you see we try to extract the
  • 00:18:15 email here and of course web Stetson
  • 00:18:18 error here for the password we should
  • 00:18:21 also use body password of course so
  • 00:18:24 password and email these are the two
  • 00:18:26 fields we'll need so let's add them here
  • 00:18:28 let's add an email test at test comm and
  • 00:18:32 let's add a password so password like
  • 00:18:37 this or maybe tester something like that
  • 00:18:40 and let's now try it out that's it's
  • 00:18:43 sent and I get an error because I need
  • 00:18:48 to set my head or a content type
  • 00:18:50 application Jason let's now try again
  • 00:18:52 and now we get user created as a message
  • 00:18:55 here and if we have a look at our
  • 00:18:57 terminal here where we do log something
  • 00:18:59 we see a user was created and this is
  • 00:19:02 this random hash I was referring to so
  • 00:19:05 this is now our password in the way it
  • 00:19:08 was stored in our database and this is
  • 00:19:12 now not possible to look up with
  • 00:19:15 dictionary tables so this is now the
  • 00:19:17 user we create it on our server so now
  • 00:19:21 we're able to sign users up there's one
  • 00:19:24 issue though if I were to send the same
  • 00:19:26 request against I hit send again then
  • 00:19:29 the user is created again so now we
  • 00:19:31 created two users with the same email
  • 00:19:33 address and chances are that you don't
  • 00:19:36 want that you want to ensure you only
  • 00:19:39 have a user with an email address once
  • 00:19:41 in your database so what can we do about
  • 00:19:44 this well we need to check if the given
  • 00:19:47 email address is still a whale
  • 00:19:49 in our sign up route so before we hashed
  • 00:19:53 a password and try to store the user
  • 00:19:55 let's do something totally different
  • 00:19:57 let's simply use the user model we
  • 00:20:00 import from Mongoose from our Mongoose
  • 00:20:02 model and find a certain object where we
  • 00:20:07 search the user entries for an email
  • 00:20:10 address where email is actually request
  • 00:20:14 body email and now we'll exit this to
  • 00:20:18 get back a promise and add then and
  • 00:20:21 catch now here in the den block
  • 00:20:24 I'll get my document so my user in the
  • 00:20:27 end and here's the part where we will
  • 00:20:30 have issues if user exists so if user is
  • 00:20:33 not knowledge or if user is not now I
  • 00:20:35 mean so if it's not false so if we make
  • 00:20:38 it into this if block we know we have a
  • 00:20:40 user and in this case I just want to
  • 00:20:42 return a response where a sends status
  • 00:20:45 code cheaver now we could use 409 which
  • 00:20:49 means conflict we got the request we
  • 00:20:52 could handle it but we got a conflict
  • 00:20:54 with the resources we already have or
  • 00:20:57 422 which means unprocess about entity
  • 00:21:00 which also pretty much means the same we
  • 00:21:02 got requests we could theoretically read
  • 00:21:05 we understand the request but we can't
  • 00:21:07 process it pick the one you enjoy I'll
  • 00:21:10 use 409 even though you don't see that
  • 00:21:12 this often now this is the error core a
  • 00:21:15 code I returned here and I can also
  • 00:21:17 attach a message where I say mail exists
  • 00:21:22 something like this with that we won't
  • 00:21:27 continue in all other cases here we will
  • 00:21:31 continue and I don't even need to catch
  • 00:21:33 block therefore however of course we
  • 00:21:35 should continue inside this then block
  • 00:21:38 here so that is where we should then try
  • 00:21:41 to hash our password and do all our
  • 00:21:45 other stuff so I'll cut this and put it
  • 00:21:48 into this else block here just to make
  • 00:21:50 sure that we only execute this if we
  • 00:21:53 don't have a user for that email address
  • 00:21:55 and now if we saved us all and I send
  • 00:21:59 the same email and password combination
  • 00:22:01 again I get
  • 00:22:02 the mail exists error and if I send a
  • 00:22:05 different one like test two I also get
  • 00:22:07 mail exists why because remember if you
  • 00:22:10 use user find like this user here is
  • 00:22:13 actually not going to be null if you
  • 00:22:16 don't find entries it's going to be an
  • 00:22:18 empty array so instead what we should
  • 00:22:20 check here is if user length is greater
  • 00:22:23 or equal to one that means we already
  • 00:22:26 have that email address and for other
  • 00:22:28 lengths like zero basically we want to
  • 00:22:32 create a new user so now if I save this
  • 00:22:34 and set this again we create the user
  • 00:22:36 but if I send it a second time we get
  • 00:22:38 mail exists so now this is working as it
  • 00:22:41 should obviously we now have the issue
  • 00:22:44 of having one wrong user entry in our
  • 00:22:47 database because we created that first
  • 00:22:48 email address twice or maybe you pressed
  • 00:22:51 the button more often so we will also
  • 00:22:54 need to clean that up and how can we
  • 00:22:56 clean it up well we can simply add a
  • 00:22:59 delete route here which allows us to all
  • 00:23:01 the delete users something we probably
  • 00:23:03 want to you have in our application
  • 00:23:05 anyways so now I will add delete route
  • 00:23:09 here and I'll just have slash user ID
  • 00:23:15 and get my request response next
  • 00:23:20 function here and in there I'll now use
  • 00:23:26 my user remove method to find users
  • 00:23:30 where the ID is equal to require to our
  • 00:23:34 request parents IDs of what we encoded
  • 00:23:37 in the URL and then I'll execute so
  • 00:23:40 basically the same what we also do for
  • 00:23:42 products and so on here with our delete
  • 00:23:44 route and then I'll add up then and a
  • 00:23:47 catch block to do something in both
  • 00:23:48 cases so then and catch here and if you
  • 00:23:54 are successful well that's great umm I
  • 00:23:57 don't really care I will just return a
  • 00:24:00 response where I set the status code of
  • 00:24:02 200 and then adjacent method where I say
  • 00:24:05 message user deleted you really see that
  • 00:24:10 it worked and if we got an error I'll
  • 00:24:12 use the same error code I have in all my
  • 00:24:15 our catch blocks here too so I'll simply
  • 00:24:18 put dad into here too now we got a
  • 00:24:21 method to delete users now we just need
  • 00:24:24 to find out that user IDs and this year
  • 00:24:28 was the user of the second test the test
  • 00:24:30 outcome user we created so this is the
  • 00:24:32 idea I want to delete so let's grab this
  • 00:24:35 and let's switch this to a delete
  • 00:24:38 request and add instead of sign up this
  • 00:24:41 ID now if I sent this I get an error
  • 00:24:45 because here I should of course access
  • 00:24:48 user ID not ID because we named it user
  • 00:24:53 ID here the path tiny mistake now if I
  • 00:24:55 sent this I get an error because I
  • 00:24:58 copied – comma – so if I remove the
  • 00:25:00 comma I get another error would see rest
  • 00:25:06 status is not a function oh yeah I
  • 00:25:11 should have named this result otherwise
  • 00:25:13 we have to rest objects and of course I
  • 00:25:15 want to refer to this one so now if you
  • 00:25:17 save this it still won't work because we
  • 00:25:19 actually did delete it just sending the
  • 00:25:20 response didn't work but I will get that
  • 00:25:22 message over and over again because we
  • 00:25:25 still make it into here because remember
  • 00:25:27 if we don't find an entry it won't fail
  • 00:25:30 doesn't throw an error so we don't make
  • 00:25:32 it into the catch block we just also
  • 00:25:34 didn't really delete anything though but
  • 00:25:37 this is fine here I now got a
  • 00:25:39 functionality to get rid off that user
  • 00:25:41 which I don't need so with that we also
  • 00:25:45 got to delete route we check if a user
  • 00:25:47 email exists before we try to create a
  • 00:25:49 new user one more thing we should do is
  • 00:25:52 we should go back to the user model and
  • 00:25:54 for the email I'll add another
  • 00:25:57 configuration which is unique which are
  • 00:26:01 also set to true now this can be really
  • 00:26:04 deceiving and and strange because you
  • 00:26:07 could expect that by setting unique you
  • 00:26:09 can basically save this code here you
  • 00:26:11 don't need to check whether an email
  • 00:26:13 address exists or not right because it's
  • 00:26:15 some form of validation just as required
  • 00:26:18 ensures that we have to pass this value
  • 00:26:20 now for a unique it's actually not the
  • 00:26:23 same unique doesn't add any validation
  • 00:26:25 on purpose instead unique simply
  • 00:26:28 optimizes this
  • 00:26:29 field you could say to be searched and
  • 00:26:31 to be indexed it can do some performance
  • 00:26:34 optimizations by knowing that there will
  • 00:26:37 be only one of these values in this
  • 00:26:38 field and that of course is helpful to
  • 00:26:40 us but it will not validate the values
  • 00:26:43 speaking of validation one more thing we
  • 00:26:46 can do though is we can add another
  • 00:26:49 conflict here to email the match config
  • 00:26:52 if type is string as it is here you can
  • 00:26:55 add some other built-in validation
  • 00:26:57 shipping with Mongoose and you can match
  • 00:26:59 that incoming string to a given pattern
  • 00:27:02 to ensure that what we're storing really
  • 00:27:04 is an email address so first of all
  • 00:27:06 distribute is over multiple lines to
  • 00:27:08 make it a bit easier to read and then we
  • 00:27:10 need a regular expression for validating
  • 00:27:13 email addresses now as all pro
  • 00:27:16 developers we can simply Google for
  • 00:27:18 email regex to find this great regular
  • 00:27:21 expression email regular expression
  • 00:27:23 discussion thread on Stack Overflow and
  • 00:27:26 there if you scroll through you'll find
  • 00:27:27 this creating an answer here where we
  • 00:27:29 got a couple of demo validation patterns
  • 00:27:32 and I'll use this one which should match
  • 00:27:34 most cases email address validation with
  • 00:27:37 regular expressions is pretty hard as it
  • 00:27:39 turns out so let's copy this and now
  • 00:27:42 match we'll take a regular expression
  • 00:27:44 created with two forward slashes and
  • 00:27:46 then simply put that expression in
  • 00:27:48 between if we do that we should get an
  • 00:27:51 error if we pass something that is not
  • 00:27:53 an email address so let's simply save
  • 00:27:55 this and let's try it out all first of
  • 00:27:58 all stick to my test email address with
  • 00:28:02 test free which doesn't exist yet I'll
  • 00:28:04 go back to a post request and target
  • 00:28:06 user sign up here and I'll hit Send and
  • 00:28:10 I get user created now let me remove let
  • 00:28:13 me remove the @ sign and now I get an
  • 00:28:16 email error validation error and that is
  • 00:28:19 actually what I wanted their email
  • 00:28:21 address is invalid and we could use that
  • 00:28:23 information in our client app and as
  • 00:28:27 soon as I riad the @ sign here like this
  • 00:28:31 I just get mail exists because it only
  • 00:28:34 does exist but it matches our pattern
  • 00:28:36 atleast so this is one on our addition I
  • 00:28:40 wanted to make and with that we added
  • 00:28:41 user signup and
  • 00:28:43 the ability to delete users in our
  • 00:28:45 routes here now the next step of course
  • 00:28:48 is to sign users in and create such a
  • 00:28:50 token