User Authentication
Easy, but Not
Strictly from a programmatic standpoint, there is nothing complicated about implementing user authentication. It's however a very challenging endeavour due to how sensitive some of the data is, and it being the primary target of attack.
Most of my APIs and logics are built to be flexible or compliant - for instance if someone finds a vulnerability in my analytics API and takes advantage of it, the worst that could happen is that footer analytics stop working. With user login data, the approach needs to be different. It needs to be solid, vulnerabilities should either not exist, or break the site when touched.
How it Works
Because of how sensitive this information is, even explaining how it was developed would defeat the basic approach to user authentication - obfuscation being the main point. I learned that protecting user data isn't so much about securing it as it is about making it as annoying as possible for someone to get it. This would include me.
I can say the following:
- Email and password information are hashed using time-consuming methods,
- These hashes are completely de-coupled from the general user data,
- This user data is only rendered on the account page (more on that below),
- All auth APIs are rate-limited.
Actions I'm more free to discuss are those available to registered users (some of these are obvious):
- You can register an account.
- You can log into an existing account.
- You can log out of an account.
- You can verify your email using a 6-digit code sent to your address.
- You can reset your password if you've forgotten it or if you want to update it*.
- You can update your username or email.
- You can delete your account.
*As implied I ended up using the same method of changing the password for both a user not able to login and a logged-in user. This seems a bit odd, but works fine for less work. I may revisit it if I'm too offput by it.
Modal JS
Every task above is powered by a all-purpose modal framework build with JavaScript. I won't share the code to GitHub as it's very specific to my website, you can always open the JavaScript file from the page source if you're curious.
Besides this framework, it was important to me not to rely on the checks made by this modal on the data being sent up. As such all data submitted through the modal gets it's own checks server-side.
Why Create an Account?
Frankly, don't.
There is no real benefit to creating an account on this website at this time, this was more-so an important milestone for its development (and will also open the door for many new goals such as an admin portal).
Technically there are some abilities which are unique to user accounts at this time:
- Your darkmode preference
- Your generated maps
- If you have maps on your account and have not generated any as guest, they will be imported on log in and remain there if you log out.
- If you have no maps on your account, but have created some as guest and log in, they will be added to your account.
- If you have generated maps as guest and also have other ones on your account, they will be merged when you log in.
While normally this preference is stored on the session, it will be saved to your acconut if you create one, which means the site will snap to your preference on login.
This refers to the Map Generator project, which will allow you to build maps, which progressively get added to a Carousel of images. This part is pretty neat: maps will be merged between session storage and account storage:
This last scenario has a caveat: the Carousel JS will only list a maximum of 14 images. Hence if you have 14 stored as guest and 14 stored on your account you will lose half of the total on merge. This is why pagination is an upcoming goal on the roadmap.
As closing words, this was pretty scary, despite not posing any real technical challenge to speak of (though I haven't stress-tested this build with many users so that could be misguided). I suppose that is a feeling a lot of backend engineers would have most of the time - second thoughts on very basic programming tasks, due to the sensitivity of the data they're working with.