Another week gone, and another set of basics covered. Let's get right into it!
Topics Covered✅
This week was all about further cementing down my fundamentals. So this week we covered the heart of any full-stack web application that is made to cater hundreds, if not hundreds of thousands of people – Databases and Authentication.
If our application intends to have multiple users, then it will need two things-
- A database - that stores all the data pertaining to different users in a sorted manner.
- Authentication - that helps you verify your users.
And as usual, I discovered these topics by the means of an assignment.
The assignment was pretty simple. It was to create a backend and connect it to a database and perform basic CRUD actions on different users.
Mongoose and JWT📎
For now, I went with MongoDB as my database, which is a noSQL database. I made a free instance, connected it with my backend.Then, I defined a User schema which was as follows.
const User = mongoose.model("User", {
name: String,
password: String,
email : String
});
This is quite a primitive example of a schema. It can be made as simple or complex as required.
Then made a couple of endpoints.
-
POST '/signup' - which would allow a new user to sign up to the application. This first checks if the submitted username already exists in the database and depending upon that it adds the user to the database. This is what the code looks like-
if (existingUser) { return res.status(400).send("user already exists"); } const user = new User({ name: username, email: emailofUser, password: password, }); user.save().then(() => res.json({ msg: "User added to database" }));
-
POST '/signin' - This would allow an existing user to sign in. By that I mean if the user does exist in the DB then it would return a signed JWT token back to the user which could be used for all future requests.
var token = jwt.sign({ username: username }, jwtPassword); return res.json({ token, });
Here jwt.sign() uses the password(which is usually top secret) to sign the username and returns the token to the user. We use
jwt.sign()
instead ofjwt.encode()
- encode just converts it into a string that can be openly decoded back to the original string whereas sign converts it into a string and also marks it with the password we give. The difference will be clearer once we cover the other endpoints. -
GET '/users' - Verifies the signed in user through the earlier returned token and then returns a list of all other users.
const token = req.headers.authorization; try { const decoded = jwt.verify(token, jwtPassword); const username = decoded.username; // return a list of users other than this username from the database const users = await User.find({ name: { $ne: username } }); res.json(users); } catch (err) { return res.status(403).json({ msg: "Invalid token", }); }
Couple of things to note here-
- We wrap this in a try-catch block because if jwt.verify() fails then it throws an error.
- We use
jwt.verify()
instead ofjwt.decode()
. The jwt token can be decoded by anyone, but verifying it requires the password with which it was signed. Thus, giving a secure authentication method.
-
DELETE '/delete' - the last endpoint to delete an entry from the database. This deletes the credentials of the signed in user from the DB.
const { name, password } = req.body; const deletedUser = await User.findOneAndDelete({ name, password }); if (!deletedUser) { return res.status(400).send("Wrong credentials"); } res.send("User deleted successfully");
There are numerous methods one can use to delete an entry in Mongoose. I used the most appropriate one here.
New things I learnt this week🔄
While I did cover mongoose this week, the thing that intrigued me the most was the distinction between verify and decode in JWT. And such an important distinction it is too.
Wrapping up
Some more fundamentals covered. Another step in the right direction. If you have any questions or feedback, make sure to comment and let me know!
I'll be back next week with more. Until then, stay consistent!
Top comments (0)