I've been doing a fair bit of web app development (single-page, CMS like stuff with user-generated content in the vein of a wiki, forum, or adjacent use space). I keep my session tokens in localstorage, websql, or indexeddb (depending on the platform, [0] is a really nice polyfill / shim to give you good key-value stores on many different browsers).<p>My session tokens are just 48 characters of base64 randomness, because that way I don't have to worry about dealing with JWT - it's a neat idea, but there have been enough bugs in the implementation that I'm still leery. Plus: this way I can expire tokens on the server side.<p>I keep session tokens stored in redis, and do an expire on them by default. Each time the token is fetched, it gets expired again (so the token actually expires N days after the last time the user visits). So yeah, each API request is burdened with two redis calls - one to verify the token and another to reset exipiry. It doesn't seem to weigh on my overall server perf - the actual API call is where most of the cpu goes (relatively speaking, it's still straightforward indexed sql queries most of the time).<p>The token is attached as a bearer token in the header of all my XHR requests.<p>The big problem is images. I work with teachers, who may want to post images of students or student work (to share with colleagues in a research project, behind security is okay, but not if those images can leak to the broader world). You can't (AFAIK) set browser-wide headers on the request that gets generated when the browser encounters an img src="url" tag. That's unfortunate, and I've played with a few options. One is: don't protect images at all - if the images aren't sensitive, then leaking them to twitter or pinterest when a user right clicks isn't the end of the world. One is: use a cookie that's only good for authenticating on the image server, and set it at app init time. One is: fetch the image data in an XHR, set the image up as a blob in the page, and set the img src attribute to the blob's dataurl.<p>None are particularly satisfying. You can crash the chrome tab (at least in chrome, I didn't test in safari / ff once I knew I was crashing chrome) if you go with the blob direction if the blob image is too large (goes OOM, then goes "aww snap"). Unfortunately, the blob approach is probably the best one if you're really worried about leaking images due to user foolishness - any user could download and re-upload an image anywhere, but you want to prevent someone from right-click, copy-image-url, tweeting the image. The blob approach prevents the image url from leaking in that situation, whereas the special-cookie approach doesn't.<p>Ultimately: we decided that we would allow images to leak if they had to - we're training users that they need to not embed potentially sensitive images inline at all. It's annoying, but there we are. Here's where session storage doesn't work as well as cookies.<p>0: <a href="https://mozilla.github.io/localForage/" rel="nofollow">https://mozilla.github.io/localForage/</a>