I have no idea how many people bounced at that step but I know I personally close tabs when something wants my email before I can even look around. So I finally added a "try without signing up" flow. This was recommended by a commenter the original post: https://news.ycombinator.com/item?id=46085379
To get this working when you press 'Try it now', I create a guest user and give you back a 'refresh' secret. That goes in localStorage. Next time you visit, we swap it for a fresh JWT. If you eventually sign up for real, your stuff transfers over.
I'm using a separate (from my auth router) JWT keypair for guests vs real users. Idea being if someone compromises the backend they can only forge guest tokens, not real ones. Secrets are hashed, guest creation is rate limited (5/hour/IP). Only real accounts can call the merge endpoint so guests can't steal each other's data.
There are some downsides. If you clear your localStorage, you've lost access. It only works on one device. And I'll need some cleanup job eventually for abandoned guest accounts sitting in the DB.
I'd be interested in other's approaches to this. I wanted to make something that mirrored my real auth flow where everything starts from a valid refresh token (the real flow uses a cookie).
https://spikelog.com if you want to poke at it. Feel free to try and break it and please let me know if you do, or how I can tighten up my security.
0 comments