Now that we’re really making progress on our project, we’ve started adding quite a few technologies and protocols to our tech stack. I thought I’d discuss the positives and negatives of various technologies I’ve interacted with on this project. For background, I’ve so far worked almost entirely on the backend, and thus haven’t really worked with the frontend tech on our stack.
MongoDB
For our database needs, we’ve been using MongoDB. I urged my team to use a NoSQL document based approach because of the nature of the text adventures that educators would be writing. The text adventures need to be stored as object files of unknown size, and only ever get pulled from the database as a whole object (we never need to check room #24 from adventure #10 if we’re not going to have the whole contents of adventure #10 available).
Working with MongoDB has been easy. They have very simple authentication, and I believe each of us were able to push to the database from the app. In fact their authentication may be too simple, as I believe we’ve leaked private connection URIs twice now. Going forward one of my main concerns will be changing the handling of the private keys.
MongoDB also has a GUI called Compass that I’ve been using to easily visualize the changes made to our database. Using Compass, I don’t need to write queries to check if data got pushed to our database, but can instead refresh and check the data. This was all very easy to set up, and MongoDB has been fun to work with.
bcrypt
After I created our database and started thinking about the kind of data we would be storing, I realized that I couldn’t just store passwords as plaintext. Previously I’d only used OAuth to authenticate users, but wanted to learn more about password storage and authentication through this project. I found an npm package called bcrypt which seemed to really simplify the process.
The b in bcrypt stands for blowfish which is a well known cipher in cryptography. I won’t get too deep into the blowfish cipher, but the key points are that it is a general purpose, symmetric-key block cipher.
- General Purpose: The cipher is designed to be versatile and applicable to a wide range of applications rather than being designed for a single type of data.
- Symmetric-Key: The same key is used for both encryption and decryption.
- Block Cipher: A block cipher is a method of encrypting data in fixed-size blocks, as opposed to streaming ciphers which encrypt data one bit or byte at a time.
Using bcrypt was really simple, and I grew to really enjoy its functionality. It even has a built in compare method that compares an encrypted text to a given plaintext, doing all of the necessary decryption itself.
Passport and JWT
Once I stored the passwords for new accounts, I still wasn’t sure what authentication would look like. After doing some research I found out about JSON Web Tokens. JWTs are a signature and authentication protocol that help verify users’ privileges. They work by encrypting authentication data according to a secret key. Essentially the function is a hashed string which you can’t escalate your privileges by editing.
I had never heard of JWTs before, but its really interesting. You can even paste the JWT I made for this example into jwt.io and see that the header, payload, and verify are all transmitted in this string:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHBpcmF0aW9uIjoiMWgifQ.46R8qgIjSyShbiETu-hukei5TRx2yk78bZQz09dQSlo
The workflow of this is as follows:
- A user logs in and the server checks that their password is the same as the hashed password it has connected to the account.
- The server grants the user a JWT with pertinent data such as username or user id as well as an expiration and the time it was granted.
- The server can use this verified token when serving further data to the user. The user can’t modify the token because it will end their authentication.
Passport.js was a tool I found that easily manages a variety of security strategies (such as JWT). I had a fair amount of trouble setting this up and wasn’t able to get it fully functional by the time our sprint ended. I’m not sure if it was a problem with the technology being difficult to understand, or if I was just having a hard time because of the already established architecture of our backend. I’m having a lot of trouble adapting documentation code from the given JavaScript to our project’s ECMA format. I probably have to read more about the differences, and honestly refactor a bunch of code anyways, so I’m not too worried actually.
Conclusion
Overall, each of the technologies we’ve added to the tech stack have been adding a lot of value to our project. Each one has its place in our project, and I don’t think any of the alternatives would offer anything different enough to warrant switching (or to even warrant worrying).
Leave a Reply