Writing

Authentication and Authorization

Authentication and Authorization

Authentication and authorization are often used together, but they answer different questions.

Authentication checks who is making a request. Authorization checks what that person is allowed to do. A signed-in user may be allowed to read a post but may not be allowed to edit it.

Authentication

A common way to sign in is with an email address and password. The account is found, and the password is checked. Passwords should be stored as hashes, not as plain text. This allows a password to be checked without keeping the original password in the database.

After a successful sign-in, the application needs a way to recognize later requests. A session or an access token can be used for this. With a token, the client sends the token with each protected request. The server checks it before treating the request as authenticated.

A JSON Web Token, or JWT, can contain an account ID and an expiration time. Its signature is used to check that its contents have not been changed. The contents of a signed JWT can still be read, so passwords and other secrets should not be placed inside it.

An access token should not be trusted only because it exists. Its signature and expiration must be checked. If the check fails, the request should be rejected.

Other ways to sign in

An application can allow sign-in through another provider, such as Google. The provider confirms the person’s identity, and the application connects that identity to an account. The application still decides what that account is allowed to do.

Two-factor authentication adds another check after the password. A short code may be sent by email or SMS. The code must be checked before sign-in is completed. This gives extra protection if a password is stolen, although the second step also needs limits on failed attempts and a short expiry time.

Authorization

Authentication does not give access to every resource. After the user is identified, permissions must be checked for the requested action.

An application may have roles such as admin, moderator, and regular user. An admin may manage all posts. A moderator may manage posts and comments. A regular user may be allowed to update only posts written by that user.

The last rule depends on ownership, not only on a role. Before an edit is allowed, the post must be loaded and its author ID must be compared with the signed-in user’s ID. The same role can be held by many users, but each post has its own author.

Permissions can be described as an action on a resource:

  • Action: read, create, update, or delete.
  • Resource: a post, comment, account, or other item.
  • Condition: an extra rule, such as “the user is the author.”

The check must happen on the server. Hiding an edit button in the browser is useful for the interface, but a request can still be sent directly to the API.

How both checks work together

When a post edit is requested, these checks are made:

  1. The access token or session is checked.
  2. The user is identified.
  3. The post is loaded.
  4. Permission to update that post is checked.
  5. The post is updated only if the check passes.

A post was written by Jack. An edit request is sent with Jack’s valid token. The token proves which account sent the request, so authentication passes. Jack is also the author of the post, so authorization passes and the edit is allowed.

The same edit request is sent with John’s valid token. Authentication passes because John’s identity is known. Authorization fails because John did not write the post. The post must not be changed. A valid token proves identity, not permission to edit every post.

If identity cannot be confirmed, the request is unauthenticated. If identity is confirmed but permission is missing, the request is forbidden. These are different failures and should be handled separately.

Authentication answers who is making the request. Authorization answers whether that request is allowed. Both checks are needed for a protected API.