跳至主要內容

Protected App — 非 SDK 驗證 (Authentication) 整合

Protected App 的設計目的是將 驗證 (Authentication) 層從你的應用程式中分離,消除 SDK 整合 的複雜性。我們負責驗證 (Authentication),讓你專注於核心功能。當使用者通過驗證後,Protected App 會從你的伺服器提供內容。

Protected App 如何運作

Protected App 由 Cloudflare 提供支援,運行於全球邊緣網路,確保你的應用程式擁有低延遲與高可用性。

Protected App 維護會話狀態與使用者資訊。如果使用者尚未驗證 (Authentication),Protected App 會將其導向登入頁面。驗證成功後,Protected App 會將使用者的請求包裹上驗證與使用者資訊,再轉發至來源伺服器。

此流程可用下方流程圖表示:

保護你的來源伺服器

來源伺服器可以是實體或虛擬設備,並非 Logto Protected App 所擁有,是你的應用程式內容所在之處。類似於內容傳遞網路(CDN)伺服器,Protected App 管理驗證流程並從來源伺服器取得內容。因此,若使用者能直接存取來源伺服器,將可繞過驗證,應用程式將失去保護。

因此,保護來源連線非常重要,可防止攻擊者在未經驗證下發現並存取你的來源伺服器。常見做法如下:

  1. HTTP 標頭驗證
  2. JSON Web Token (JWT) 驗證

HTTP 標頭驗證

你可以使用 HTTP 基本驗證 (HTTP Basic Authentication) 來保護來源伺服器。

每個來自 Protected App 的請求都會包含以下標頭:

Authorization: Basic base64(appId:appSecret)

透過驗證此標頭,你可以確認請求來自 Protected App,並拒絕未包含此標頭的請求。

若你使用 Nginx 或 Apache,可參考下列指南於來源伺服器實作 HTTP 基本驗證:

  1. Nginx:設定 HTTP 基本驗證
  2. Apache:驗證與授權 (Authentication and Authorization)

若需於應用程式內檢查標頭,可參考 Cloudflare 提供的 HTTP Basic Authentication 範例,瞭解如何使用 HTTP Basic 機制限制存取。

JSON Web Token (JWT) 驗證

另一種保護來源伺服器的方法是使用 JSON Web Token (JWT)。

每個經驗證的 Protected App 請求都會包含以下標頭:

Logto-ID-Token: <JWT>

此 JWT 稱為 ID 權杖 (ID Token),由 Logto 簽署並包含使用者資訊。驗證此 JWT 可確認請求來自 Protected App,並拒絕未包含此標頭的請求。

權杖以 JWS 權杖格式加密並簽署。

驗證步驟如下:

  1. 驗證 JWT
  2. 驗證 JWS 簽章
  3. 權杖的簽發者 (Issuer) 為 https://<your-logto-domain>/oidc(由你的 Logto 驗證伺服器簽發)
const express = require('express');
const jwksClient = require('jwks-rsa');
const jwt = require('jsonwebtoken');

const ISSUER = 'https://<your-logto-domain>/oidc';
const CERTS_URL = 'https://<your-logto-domain>/oidc/jwks';

const client = jwksClient({
jwksUri: CERTS_URL,
});

const getKey = (header, callback) => {
client.getSigningKey(header.kid, function (err, key) {
callback(err, key?.getPublicKey());
});
};

const verifyToken = (req, res, next) => {
const token = req.headers['Logto-ID-Token'];

// 確認請求包含 Logto-ID-Token 標頭
if (!token) {
return res
.status(403)
.send({ status: false, message: 'missing required Logto-ID-Token header' });
}

jwt.verify(token, getKey, { issuer: ISSUER }, (err, decoded) => {
if (err) {
return res.status(403).send({ status: false, message: 'invalid id token' });
}

req.user = decoded;
next();
});
};

const app = express();

app.use(verifyToken);

app.get('/', (req, res) => {
res.send('Hello World!');
});

app.listen(3000);

取得驗證狀態與使用者資訊

若你需要取得應用程式的驗證狀態與使用者資訊,也可以使用 Logto-ID-Token 標頭。

若你僅需解碼權杖,可參考以下程式碼:

const express = require('express');

const decodeIdToken = (req, res, next) => {
const token = req.headers['Logto-ID-Token'];

if (!token) {
return res.status(403).send({
status: false,
message: 'missing required Logto-ID-Token header',
});
}

const parts = token.split('.');
if (parts.length !== 3) {
throw new Error('Invalid ID token');
}

const payload = parts[1];
const decodedPayload = atob(payload.replace(/-/g, '+').replace(/_/g, '/'));
const claims = JSON.parse(decodedPayload);

req.user = claims;
next();
};

const app = express();

app.use(decodeIdToken);

app.get('/', (req, res) => {
res.json(req.user);
});

app.listen(3000);

自訂 ID 權杖宣告 (Claims)

預設情況下,Logto-ID-Token 標頭包含標準 OIDC 宣告(如 subnameemail)。若需包含 擴充宣告(如角色或組織資料),需同時設定以下兩項:

  1. 租戶開關:於 Console > Custom JWT > ID token 啟用該宣告。
  2. Protected App 權限範圍 (Scopes):於 Protected App 設定中,在 ID 權杖宣告 > 額外權限範圍 (Additional scopes) 選擇對應範圍。

僅當 Custom JWT 啟用該宣告且 Protected App 選擇對應權限範圍時,擴充宣告才會包含於轉發的 ID 權杖中。完整擴充權限範圍與宣告請參閱 自訂 ID 權杖

權限範圍 (Scope)宣告 (Claims)
custom_datacustom_data
identitiesidentities, sso_identities
rolesroles
urn:logto:scope:organizationsorganizations, organization_data
urn:logto:scope:organization_rolesorganization_roles

取得原始主機

若需取得用戶端請求的原始主機,可使用 Logto-Hostx-forwarded-host 標頭。

自訂驗證規則

預設情況下,Protected App 會保護所有路由。若需自訂驗證規則,可於 Console 設定「自訂驗證規則」欄位。

支援正則表達式,以下為兩種情境範例:

  1. 僅保護 /admin/privacy 路由:^/(admin|privacy)/.*
  2. 排除 JPG 圖片不進行驗證:^(?!.*\.jpg$).*$

本地開發

Protected App 設計用於搭配你的來源伺服器運作。若來源伺服器未公開於網際網路,可使用 ngrokCloudflare Tunnels 等工具將本地伺服器暴露至網路。

過渡至 SDK 整合

Protected App 旨在簡化驗證流程。但若你希望獲得更高控制與自訂性,決定轉換為 SDK 整合,可在 Logto 建立新應用程式 並設定 SDK 整合。為順利過渡,可重複使用 Protected App 的應用程式設定。Protected App 實際上是 Logto 中的「傳統網頁應用程式 (Traditional Web App)」,你可於應用程式設定中找到「AppId」與「AppSecret」。過渡完成後,可將 Protected App 從應用程式中移除。

Protected App:點擊即可建立應用程式驗證 (Authentication),無需寫程式。

Protected App 的設計動機

建立驗證 (Authentication) 系統的最快方式