Replace JWT authentication with database-backed sessions #9
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Currently, when a user logs in to the application, the server provides them with a signed JSON web token asserting their identity. On subsequent requests, the user presents this token, and the server authenticates the user by verifying the signature on the token.
While the use of a signed objects enables a relatively lightweight authentication scheme, it requires several security tradeoffs compared to traditional database-backed sessions:
In addition, the JWT standard in particular enables a number of options, specified in the token itself, that are not necessary or desirable for single-app authentication tokens, including public/private key signatures and the option to disable authentication entirely with
{"alg": "none"}
. While most mature JWT library implementations take care to validate the provided algorithm and other values, these features remains a source of unnecessary complexity and potential security bugs.Consequently, this PR removes the use of JWTs as an authentication token, and replaces them with a random string (16 bytes from
crypto.randomBytes
, base64 encoded) that is used to look up the session information in a database table (sessions
).Sessions now expire after an hour of inactivity, rather than a flat hour after login. Additionally, an
/auth/logout
endpoint will invalidate a session immediately. For simplicity, when a user logs in, any other existing sessions they might have are also invalidated.This PR also removes client-side validation of the token[1], and causes the "sign out" link to post to the logout endpoint in addition to discarding the token locally.
[1] Currently, when the application front-end loads, and a token exists in
sessionStorage
, the app checks whether the token is expired to determine whether to treat the user as logged in. In the absence of this check, the app attempts to retrieve/api/account
and fails, ending up in the same UI state anyway.