Published
- 13 min read
Tessera Lab 4 - Profile, Users, and Tickets
Objective
In this lab, we’re diving into the nitty-gritty of user accounts and profiles. We’ll set up a smooth login and registration flow, making sure our users can securely log in and manage their profiles. We’ll be working with JWTs (JSON Web Tokens) to keep things secure, using cookies to store our tokens. Plus, we’ll add some backend magic to handle ticket inventory for events. By the end of this lab, you’ll have a fully functioning user account system and a robust backend for managing event tickets. Let’s get to it!
Quick Note
We’re at the point in our labs where you have experience with almost everything you need to build the best Tessera you can. All the other older labs will always be availible for you to go back and read through. If you’re still not fully comfortable with one thing or another, thats okay! Asking questions is how we learn. Going forward, these labs will be more of an outline rather than telling you exactly what do. This is for 2 reasons
- Full Stack engineering requires you to solve complex problems every step of the way. Its time to get that experience. The cycle of design -> build -> test -> iterate is why we do what we do. Copy pasting code given to you is a great way to learn and see how things COULD be done, but its impractical to accept that will always be the case
- We’re all building our own tessera. I should not see everyone’s screen looking the same!! Enngineers are modern day wizards - explore your creative side. Think of ideas and systematically design and build them! Want to use a totally different UI library? Do it! Want to change the color of the buy button? DO IT!!!
This dosent mean you’re on your own. In fact, theres specifc features that we will build and I may enforce them to be built a certain way (things like similar schemas, similar flows, similar API structures). This is so that future labs dont become impossible depending on design choices you’ve made. Dont worry though - still plenty of room for creativity!
Introduction to User Accounts and JWT
User accounts are fundamental to many web applications, allowing users to have personalized experiences and access to protected resources. When users create accounts, they provide credentials—typically a username and password—that uniquely identify them and grant access to their private data and application features. Ensuring that this authentication process is secure is critical to protect user information and prevent unauthorized access.
One common approach to secure authentication is to use JSON Web Tokens (JWTs). JWTs provide a way to securely transmit information between parties as a JSON object. This information can be verified and trusted because it is digitally signed.
Understanding JSON Web Tokens (JWT)
A JSON Web Token (JWT) is a compact, URL-safe token composed of three parts: a header, a payload, and a signature. Here’s a breakdown:
- Header: The header typically consists of two parts: the type of token (JWT) and the signing algorithm (e.g., HMAC SHA256). It looks like this:
{
"alg": "HS256",
"typ": "JWT"
}
- Payload: The payload contains the claims. Claims are statements about an entity (typically, the user) and additional data. Here’s an example payload:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
- Signature: To create the signature part, you take the encoded header, the encoded payload, a secret, and sign that. The signature is used to verify that the sender of the JWT is who it says it is and to ensure that the message wasn’t changed along the way.
The JWT looks like this when encoded:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
How JWTs Help in Verifying Users
When a user logs in, the server verifies their credentials and, if they are correct, generates a JWT. This JWT is then sent back to the client (usually stored in a secure, HttpOnly cookie). On subsequent requests, the client includes the JWT, allowing the server to verify the user’s identity without needing to check the database every time. This stateless authentication method is efficient and scalable.
For example, upon successful login, the server might generate and send a token like this:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
The client can then include this token in the Authorization header of subsequent requests:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
On the server side, each protected route checks for the token, verifies it, and grants access if the token is valid. This ensures that only authenticated users can access certain endpoints, providing a secure way to manage user sessions and protect sensitive data.
Task 1 - Incorporate JWTs into our backend
JWTs are dope. Lets learn how to use them. Our backend is written in python so lets find a standard JWT library we could use with python + Flask. Lets use this one!
Take some time to read the docs, the basic guide, the examples. Question for you, when generating the jwt, how do we define what data is in the Payload
section? In tessera, what user data might we want to include in our payload? What data should we probably not include?
Time to Code. As promised, a list of requirements but no hand holding today :)
- Modify the current login endpoint to generate a JWT for the user and return it. Make sure you include any profile information you think is important to encode. Determine a good expiration time for each token. Feel free to read about the libraries implementation of ‘Token Refresh’ (Although I wont require you to implement this)
- Take inventory of all your API endpoints. Determine which endpoints should be accessible only by logged in users. Lock down the endpoints so that only someone with a valid JWT can call them. Keep in mind end-user functionality. Think about websites like Amazon, Ticketmaster, Ebay etc. Anyone can view products and services - but only registered users can take actions such as purchasing
What does an API response look like when you try to call these new protected APIs without a valid token? Whats the status code? What do you think should happen if someone’s browser made this request but the user wasn’t logged in? Start thinking about these things! We’ll get to these problems very soon!
User profiles
We built our schemas for our users a few labs ago. We then built out APIs to support creating users and logging in! It’s time to add user profiles to our front end!
Task 2 - Login, Logout, Registration, and Profile Page!
- Create a new page that you can navigate to by going to
/login
in your browser. - Using our component library, design a login page. It can be as fancy as you want! Take some inspiration from your favorite websites! Create your component(s). I like to keep my logins very simple. Heres what mine looks like
- Make it work! When someone tries to login, call your backend, to login and if successful - route them to the homepage!
- Make sure you think about what happens when its invalid! Heres what my page shows: Does the error message matter? Whats an error message we SHOULDNT put here?
- What happens if our server is slow… maybe the user is on mars and each request is taking 751 seconds for the request to reach us? Do we want the user to be able to click login over and over and over again? Think of a solution for this. HINT
- Build the registration page (have it at
/register
). We have a registration endpoint we built in a previous lab we should utilize! What validations do we need? Whats required and whats not? What are some errors that could arise? How can we handle them? After someone registers, where should we take the user? Make sure to link the user to the registration page from your login page too! Here’s my version: - Recall that we have a nav bar that follows our user everyone on teserra (maybe you hid it on the login and registration page? Did you think about this 🤔). You should have a profile button or section on the top right of the screen. This usually leads the user to a page to manage their accounts. Lets build that! Ill leave the design 100% up to you at this point. Allow the user to update information about their account. Maybe they have a new email address, maybe your version of tessera allows usernames, maybe it also stores phone numbers! Profile pictures👀👀👀???? This may require some new API endpoints to be built or modified. You’ll come across some questions here around accessing your JWT and some limitations. Think through this! Get those gears turning on how we can (securely) get over these hurdles! Stuck? Come to me and well talk though it. Here’s my (very) simple implementation:
- EXTRA CREDIT (Not required): My implementation allows a user to upload a photo for a profile image. Implement this. How do we store images? How do we allow users to upload images? This is a new space for you - but do some research! A lot of resources out there. Talk to me before continuing with your idea.
- EXTRA CREDIT (Not required): Allow the user to change passwords. This may require some API work. Your choice how you want to handle this. A new page? A section in your user settings page?
Theres some things I dont want you do yet. You may have experience where you need to “verify” your email address when signing up for a new account on a website. This is so that no one can make an account on your behalf. If you had this thought - good, I’m proud of you! We need a bit more intuition before we build something like this so lets not work on it yet!
Ticket inventory
Lets switch gears. We have events and users now. But we need tickets! We are getting REALLY close to being able to ‘sell’ tickets to users! Lets do some backend and database work to get ready for our buy flow.
Task 3 - Ticket Inventory design
We created a ticket table really early on. The purpose at the time was to introduce tables and relationships between them. Unfortunately I lied to you. We’re going to need to redesign this table now that we’ve leveled up and understand the system as a whole. You didn’t think I was going to design the whole thing for you in Lab 1 did you 😉. Lets delete our tickets table and define some new requirements.
- We want to create a new table and schema. Lets create a new table called tickets with the following columns
- eventId (Foreign key to our events table)
- rowName (Lets assume these will be letters like A, B, C…)
- seatNumber (Lets assume these will be numbers like 1, 2, 3, 4…)
- status (This will be where we store if the seat is AVAILIBLE, RESERVED, or SOLD). This will be a string BUT I want you to think about how we can make sure that this field can ONLY be one of a predefined list of strings. You may be familiar with Enumerated type (Enums). While SQLITE dosent have the concept of Enums (some database engines do) it does have the CHECK constraint. How could we use this?
- What will be the primary key here? Remember, we always need a primary key. Recall our lectures about compound keys! How do we create compound keys in sqlite?
- How will we assign tickets to users? Maybe you want to create a new table that stores barcodes and tickets? Maybe you want to include new columns on the actual ticket? Think about this and come up with a solution. Run this by me once you have a design.
- Prices!! How do we want to handle prices? Do we really want to manually set prices for every single ticket? Do we want to allow maybe group pricing? Do we want to charge the same price for front row seats and nosebleeds (no we dont that boring). Come up with a way manage pricing. I dont want a solution resembling a new column for each ticket with the price - think about something that is extendable.
- Now that we have a real ticket inventory table, we want to fill it with tickets! For each event you have, come up with multiple rows with multiple seats per row. Insert them into your schema so they’re ready to sell. How could you speed this up? I dont want to see 38798723 Insert statements. Maybe you could write a python script? I personally wrote a python script that allowed me to provide an event name, number of rows, and number of seats per rows and it would create the event and tickets… maybe… you could even… create a API endpoints 👀? Where else could this functionality be used?
Task 4 - Inventory APIs
Nice job - what time is it? If its past 2am go to bed. Otherwise we’re not done yet! We have a nice database schema and we have data. We’re going to need APIs to expose this inventory.
- Design and build a set of inventory/ticket APIs. Keep in mind the following use cases
- We will need to display to the user what seats are available and which are sold out for an event
- We need to make sure we dont expose who owns seats when talking about inventory. Security!!
- A ticket will go into a ‘RESERVED’ state when the user selects is but hasn’t completed the purchase.
- A ticket could also be unreserved!
- We should support a user selecting and purchasing multiple seats
- Think about what endpoints need to be protected
You should be comfortable designing APIs at this point. Do not hesitate to run your designs by me before you start building!
Conclusion
Whew, that’s A LOT of work. I really want you to take a step back and be impressed with how far you’ve come. You’ve tackled some pretty advanced concepts, from setting up secure user authentication to managing state with JWTs and cookies, and building a robust backend to handle event tickets. Each step you’ve taken is a building block toward becoming a proficient full-stack developer.
Remember, every line of code you write, every bug you fix, and every new concept you learn is a testament to your growth and determination. You’re not just learning to code; you’re learning to think critically, solve problems, and build solutions that can make a real impact.
Keep pushing forward, stay curious, and don’t be afraid to make mistakes—they’re just opportunities to learn and improve. You’re building a solid foundation that will support you in any tech journey you choose to embark on. Be proud of what you’ve achieved, and get excited for what’s next. The skills you’re developing now are the keys to unlocking a world of possibilities in the tech industry.
Great job - get ready for the final stretch. See you in Lab 5.
”Software developers are the wizards and shamans of the modern age.”