So in building my first web application with Sinatra, I quickly realized that enabling sessions has many more use cases than just handing out cookies and signing users in and out. After all, the HTTP is a stateless protocol and that means sometimes you desperately need a way to pass arguments between different routes when it makes sense to do so. Enter, the session hash.
So you begin by enabling sessions and setting a session secret to keep our session data safe (although sessions will still work without a session secret, it's normally a good idea to use a randomly generated string of characters generally between 24 to 32 bytes long in order to help prevent malicious attacks).
Once you've done that, the most common practical use is for handling the login/logout process of a user. Once we've authenticated a user, we log that person in by creating a key inside the session hash and storing that user's ID as its value.
This is important because each time we need to check whether a person is logged in, we can simply see whether we can find that user in the database based on the user ID that's stored inside the session hash.
But just because that's what it's most commonly used for it doesn't -- or shouldn't -- limit how we use our session hash.
For instance, perhaps you need to store foreign keys and use that data when necessary to create associations where needed:
Or perhaps you need to store a message to show the user that an action was properly executed:
So you see, it doesn't really matter WHAT you store. Whatever information you need persisted between each request can be stored in the session hash and utilized accordingly. This opens up and provides numerous ways in which the application can function more flexibly even as we navigate through a stateless protocol.