There are two main ways in which a server can verify that a client is a certain user: signed tokens and sessions.
A signed token is piece of data that is cryptographically signed—which means we can mathematically verify who wrote the data. When the data is a user ID, for example 123, and the signer is someone we trust (either our server, or a trusted third-party server when we’re using an authentication service like Auth0), then we can verify the signature and know that the client is user 123. The most common type of signed token is a JWT, or JSON Web Token.
A session is a period of time during which a certain client is considered logged in as a particular user. The server stores data about the session, for instance:
And gives the client a secret: in this case, the sessionId. Whenever the client contacts the server, the client includes the secret so that the server can look up the session data. For instance, if the client sends 'abc', the server can look up the above record, and if the session hasn’t expired, the server knows the client is user 123.
Both methods can contain additional information about the user—information commonly included in order to prevent the server from having to take the time to look up the user record from the database. For example, we could include authorization info like isAdmin or profile info like name and email.
There are some pros and cons to each method:
The differences are small enough that for most applications, we recommend using whichever method is easier to build.
We can store session secrets and signed tokens in either localStorage or cookies, which have different pros and cons:
While the XSS issue is a serious concern, a common mitigation is setting short expirations, and for applications without strict security requirements, we again recommend using whichever method is easier to set up.