Skip to content

Authorization

rocambille edited this page Apr 28, 2026 · 1 revision

Summary: This page explains how to centralize and apply secure access rules (e.g., "owner-only access") using req.me and injected entities.

The principle of authorization

Authorization happens after authentication. Once we know "who" the user is (req.me), we must verify if they have the right to perform the requested action on a specific resource (e.g., req.item).

Centralization in routes

In StartER, we recommend placing authorization logic directly in the module's routes file (e.g., src/express/modules/item/itemRoutes.ts). This makes the rules easy to audit.

Example: verifying resource ownership

const checkAccess: RequestHandler = (req, res, next) => {
  // req.item was injected by the param converter
  // req.me was injected by verifyAccessToken
  if (req.item.user_id === req.me.id) {
    next(); // User is the owner, proceed
  } else {
    res.sendStatus(403); // Forbidden
  }
};

Fine-grained application with .all()

To protect all HTTP methods of a specific path, you can use .all():

router
  .route("/api/items/:itemId")
  .all(checkAccess) // Applies to all methods below
  .put(itemValidator.validate, itemActions.edit)
  .delete(itemActions.destroy);

The authentication wall

To avoid repeating the verifyAccessToken call on every route, you can define a security boundary:

// Public routes (read-only)
router.get("/api/items", itemActions.browse);
router.get("/api/items/:itemId", itemActions.read);

// --- BOUNDARY ---
router.use("/api/items", authActions.verifyAccessToken);

// Protected routes (writing)
router.post("/api/items", itemValidator.validate, itemActions.add);

Best practices

  1. Explicit over implicit: don't hide authorization too deep in repositories or actions. It should be visible at the routing level.
  2. Fail fast: reject the request as soon as possible (middleware) before validating the request data.
  3. Use req.me: never rely on a user ID sent by the client (req.body.user_id) to verify rights; always use the session identity req.me.

See also

Clone this wiki locally