剛進公司時,被指派了寫上團購系統前台後台的登入系統,是這樣的,後台管理員還有不同的角色,每個角色所擁有的權限也不一樣。所以可以希望透過 Middleware 來做權限的控管。

在這個專案中,我們使用了 Express 來做為後端的框架,至於 Middleware 要怎麼使用就不在贅述了。

一開始當然寫得簡單的方法就是這樣:

app.use("/admin", (req, res, next) => {
  if (req.session.role !== "admin") {
    res.status(403).send("Forbidden");
  } else {
    next();
  }
});

但後來發現,團購系統中有團主的身份,這身份比 Admin 來得低,於是有些 API 就必須這樣做:

app.use("/admin/orders", (req, res, next) => {
  if (req.session.role === "admin" || req.session.role === "group_owner") {
    res.status(403).send("Forbidden");
  } else {
    next();
  }
});

後來覺得這是可以透過 JS 的 Arrow Function 來簡化的,我們可以直接定義一個 func 並直接回傳驗證的方法:

const checkRole = (roles) => (req, res, next) => {
  if (roles.includes(req.session.role)) {
    next();
  } else {
    res.status(403).send("Forbidden");
  }
};

這樣我們就可以這樣使用:

app.use("/admin", checkRole(["admin"]));
app.use("/admin/orders", checkRole(["admin", "group_owner"]));

簡化了!

結論

其實說是回傳 Callback Function,但可以控制這 Callback Function 執行的條件,簡化程式碼。

而外的例子也可以用在 Logging 上,可以把 不要做 Log 的條件寫在外面,這樣就不用每個地方都寫一次了。