Skip to content

Instantly share code, notes, and snippets.

@szemate
Last active March 17, 2022 17:57
Show Gist options
  • Save szemate/e1a6dd8d5277b2fa5447f5c8ccb843de to your computer and use it in GitHub Desktop.
Save szemate/e1a6dd8d5277b2fa5447f5c8ccb843de to your computer and use it in GitHub Desktop.
Stateful Token Authentication

Stateful Token Authentication

  1. Create a tokens table in the database with two columns:
    • token text field, primary key
    • user_id foreign key to the users table
  2. In the POST /login request handler, after checking the user name and the password, generate a new token. It can be done using the uuid Node module (https://github.com/uuidjs/uuid). The token will look something like 1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed.
  3. Insert the new token into the tokens table.
  4. Include the token in the JSON object in the HTTP response.
  5. The frontend should store the token in the global state (the same way it already stores other user parameters).
  6. When the frontend sends a HTTP request to a protected endpoint, it should include the token in the Authorization header in the format Authorization: Token 1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed. Using fetch it looks something like
    fetch("/api/myresource/", {
      headers: {"Authorization": `Token ${token}`}
    })
  7. The request handler can access the Authorization header as req.headers.authorization. If the frontend doesn't send the header, the backend should respond with 401 Unauthorized status.
  8. As the header's value is in the format Token 1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed, split the string at the white space character to get the token. If the header is in the wrong format, return 400 Bad Request status.
  9. Create a function that selects the user from the database based on the received token. It can be done by joining the tokens and users tables together.
  10. If the query doesn't return a user then the backend should respond with 401 Unauthorized status. Otherwise, the returned user ID can be used to proceed with the request and select the user's private data from the database.

Stretch goals

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment