web authentication and authorization

Theory, Umbrella term: Identity and Access Management (IAM) - Access Control

libs

libs for rolling out your own auth system:

Providers

Identity-as-a-Service (IDaaS) and Customer Identity and Access Management (CIAM).
3rd party auth services that offload the trouble of implementing your own system

they all offer a free tier of 25-50k monthly active users (except WorkOS 1M)
Clerk, Auth0 and WorkOS manages RBAC. You are able to define them in a dashboard UI
with firebase and supabase you have to define your own DB tables for roles and permissions and Supabase auth hooks are able to query the DB and embed that data into the JWT b4 sending to client.

since roles and perms live in the JWT you just have to decode the token once when the request comes in and add it to context.

steps to implement auth

  1. choose how user will authenticate
  1. Choose Sessions or jwt and refresh tokens to have user sessions.
  2. Persist sessionId or JWT in Cookies or LocalStorage.

Restoring session / State

to persist user data after site is closed and reopened, instead of storing user payload data in local storage (like I've done in past projects), Everytime user comes to website, make an API call (along with the user's cookie) and let server decide who the user is.
Pasted image 20240726130312.png
Pasted image 20240726130337.png
(remember we can't decode HttpOnly cookies in the browser)

ID token vs Access token

ID token: OpenID Connect (OICD)
Access token: OAuth2 auth protocol

Access tokens (also called Bearer tokens) authorizes an application to access resources or make actions on behalf of the user. For example: a Microsoft access token gives your app permission to access the users files in OneDrive or Microsoft Graph(API).

When a user logs in with Google using OAuth2 they generally have to consent to the specific resources the app asks for.

OpenId Connect is for granting id token that identifies the user. OpenId piggy backs on existing 3rd party auth servers to identify the user on our app. It is not interested on any 3rd party resource or access token.

ID tokens:

OAuth2 is like giving an app a key, the key is useful but it doesn't tell the app who the user is or anything about him. OIDC is like giving the app a badge, the badge gives the client specific permissions but also providers basic info about the user.

ID tokens must be JWT, access token can be any string but usually is in JWT format.

id-token-vs-access-token.jpg

some more in depth videos of how Oauth and OIDC work

Mixed tokens

It's very common nowdays to implement a mix between ID tokens and access tokens in a single JWT.

For example in snapshot we have:

// Compressed JWT payload interface
export interface JwtPayload {
  sub: string; // subject (user ID) - standard JWT claim
  oid?: string; // organization ID - compressed from 'organization_id'
  rol?: string; // role (permission level) - compressed from 'permission_level'
  eml?: string; // email - compressed from 'email'
  iat?: number; // issued at - standard JWT claim
  exp?: number; // expiration - standard JWT claim
}

While the official OpenID Connect (OIDC) spec says "ID Tokens are for the client" and "Access Tokens are for the API," most modern developers find it redundant to send two different JWTs to the API.

By combining them, your API doesn't have to make a second "Who is this?" request to a database or identity provider. It has everything it needs to perform a Permissions Check (like your CASL rules) immediately upon decoding the token.