- Fork and clone this repository to your
Development
folder.
After forking the repository, you will find a fully functional url shortener!.
The goal is to prevent any unauthorized user from using our service.
- In
users.controllers
, create a method calledsignup
. - Install
bcrypt
and require it inusers.controllers
. - Hash the password with
10
salt rounds and overwritereq.body.password
with the new, hashed password. - Pass the body of the request to
User.create
. - Change the response status to
201
and end it with a message.
Generate a token in users.controllers
's signup
method.
- Install
jsonwebtoken
. - Require
jwt
fromjsonwebtoken
. - In
users.controllers
, create a function calledgenerateToken
that takesuser
as an argument. - In this function, create an object called
payload
and pass it the user'susername
that's coming fromuser
. - Keep in mind that the token must have the user's ID and the expiration date of the token.
- Add an
exp
property topayload
and its value is the date right now plusJWT_EXPIRATION_MS
. - After creating your
payload
object, calljwt.sign()
and pass it two arguments:payload
, make sure to stringify it.JWT_SECRET
- Save the returned value in a variable called
token
and returntoken
. - In the
signup
method, after creating the user callgenerateToken
and pss it the new user. - Save the returned value in a variable called
token
and send it as a response.
- Install
passport
andpassport-local
. - Require
passport
inapp.js
. - Call the
app.use
method and pass itpassport.initialize()
.
- In
middleware
, create a file calledpassport.js
. - Require
LocalStrategy
frompassport-local
. - Create a variable called
localStrategy
that's equal to aLocalStrategy
instance. - Pass
LocalStrategy
an asynchronous function as an argument. This function receives three parameters:username
,password
anddone
. - Add a
try catch
statement in the function. In thecatch
block, calldone
and pass iterror
. - Look for a
user
in theUser
model that has theusername
that's passed to the local strategy. Save it in a variable calleduser
. - Don't forget to import
User
. - Import
bcrypt
. - If
user
exists, callbcrypt.compare()
and pass itpassword
anduser.password
for comparison. - Save the returned value in a variable called
passwordsMatch
. - If
user
doesn't exist, setpasswordsMatch
tofalse
. - If
passwordsMatch
istrue
, returndone()
and pass it two arguments,null
anduser
. - Else, return
done()
and pass it two arguments,null
andfalse
. - In
app.js
, require thelocalStrategy
instance that we just created. - Under the passport initialization, call
passport.use()
and pass itlocalStrategy
. - In the
/signin
route, callpassport.authenticate()
and pass it "local
" and{ session: false }
as arguments. - Test your route in Postman.
- Create a new folder called
config
. - In this folder create a file called
keys.js
. - Create an object that has two properties:
JWT_SECRET
: give it a secret key.JWT_EXPIRATION_MS
: give it the time for your token expiration in milliseconds. - Export this object
Generate a token in user
controller's signin
function.
- Require
JWT_EXPIRATION_MS
andJWT_SECRET
fromconfig/keys.js
. - Install
jsonwebtoken
. - Require
jwt
fromjsonwebtoken
. - In the
signin
function, create an object calledpayload
and pass it theuser
's information that's coming fromreq.user
. - Keep in mind that the
token
must have theuser
's ID and the expiration date of the token. - Add an
expires
property topayload
and its value is the date right now plusJWT_EXPIRATION_MS
. - After creating your payload object, call
jwt.sign()
and pass it two arguments:payload
, make sure to stringify it.JWT_SECRET
- Save the returned value in a variable called
token
. - Send
token
as a json response.
-
In the user controller's signup function, create a payload object that takes its details from newUser and encrypt it.
-
Pass the token as a reponse.
-
Start with installing the
JWT strategy
. -
In
middleware/passport.js
requireJWTStrategy
. -
We will create a JWT strategy instance, which takes two arguments, an
options
object and a callback function. -
Tokens can be extracted from the request in many ways. We will pass our token in the request's authorization header with the scheme bearer. We need to require
fromAuthHeaderAsBearerToken
. -
Now we will pass this method to our
options
object. Also, we will pass oursecret key
we defined inconfig/keys.js
. -
Now the second argument, an asynchronous callback function, takes two arguments, the token's payload and done method. So the JWT strategy decodes the token and passes the payload as an argument.
-
Check if the token is expired or not by comparing the expiration date to the date right now. If the token is expired, call
done
and pass itnull
andfalse
as arguments, which will throw a401
error. -
If the token is not expired, we will find the
user
with the ID saved in the token. You can usefindOne
and pass it theusername
. Then we will pass the founduser
todone
. If nouser
is found, it will throw a401
error. -
Let's initialize our strategy in
app.js
. RequirejwtStrategy
and pass it topassport.use()
.
In the shorten
, use req.user
instead of the route param.
If the user is not the one who created the url, don't allow him to delete it!