This question comes up all the time on HN. I'm one of a bunch of people on HN that do this kind of work professionally. Here's a recent comment on a recent story about it:<p><a href="https://news.ycombinator.com/item?id=16006394" rel="nofollow">https://news.ycombinator.com/item?id=16006394</a><p>The short answer is: don't overthink it. Do the simplest thing that will work: use 16+ byte random keys read from /dev/urandom and stored in a database. The cool-kid name for this is "bearer tokens".<p>You do not need Amazon-style "access keys" to go with your secrets. You do not need OAuth (OAuth is for <i>delegated authentication</i>, to allow 3rd parties to take actions on behalf of users), you do not need special UUID formats, you do not need to mess around with localStorage, you do not need TLS client certificates, you do not need cryptographic signatures, or any kind of public key crypto, or really any cryptography at all. You almost certain do not and will not need "stateless" authentication; to get it, you will sacrifice security and some usability, and in a typical application that depends on a database to get anything done anyways, you'll make those sacrifices for nothing.<p>Do <i>not</i> use JWTs, which are an increasingly (and somewhat inexplicably) popular cryptographic token that every working cryptography engineer I've spoken to hates passionately. JWTs are easy for developers to use, because libraries are a thing, but impossible for security engineers to reason about. There's a race to replace JWTs with something better (PAST is an example) and while I don't think the underlying idea behind JWTs is any good either, even if you disagree, you should still wait for one of the better formats to gain acceptance.