命名的難度在於如何讓變量、常量、函數或類的定義清晰而簡潔,而不應有歧義。如果我們不能清楚地看懂某個變量,那麼這個變量的命名就不太準確。
API key 和 token 就有這種問題,它們都是作為一種身份驗證機制。前幾天我在一次討論中,有人提到這兩個詞可以互換使用。大約兩分鐘後,我不得不停止談話並說 "你們應該知道它們是不同的,對吧?",說完會上鴉雀無聲,顯然他們不知道。事實證明,很多人都無法告訴我 API key 和 token 之間的區別。因此文本我將向大家介紹它們之間的區別。
定義#
我們可以通過以下定義來區分 API key 和 token。
1、API key — 通過代碼調用 API 時提供的值,用於識別和授權調用者。它旨在以編程方式使用,通常是一長串字母和數字。
2、token — 代表用戶會話或特定權限的一段數據。供個人用戶在有限的時間內使用。
生成方式#
兩者之間的創建方法通常也不同。
1、API key — 通常通過用戶界面創建一次,並且在輪換之前可以一直使用,也可以選擇配置為在一定時間後過期。
2、token — 在成功驗證或登錄成功時動態生成。通常過期時間較短,但可以刷新較長時間。
權限範圍#
權限範圍是指授權部分或使用提供的身份驗證方法時可以執行哪些功能。
1、API key — 固定的、不變的應用程序功能權限集。誰擁有 API key 就可以訪問允許的資源。
2、token — 僅限於個人有權訪問的特定數據或功能。這可能會受到角色或其他業務級別要求的影響。往往更關注數據限制。
安全性#
它們的安全性如何?如果 API key 或者 token 被惡意用戶洩露或獲取,潛在的損害有多嚴重?
1、API key — 由於這些密鑰通常是長期存在的並且不限制對數據的訪問,因此如果被洩露,可能會造成毀滅性的後果。通常撤銷 API key 是解決問題的唯一手段。應用程序通常需要具有良好的可觀察性,以識別受損密鑰並找到惡意用戶。
2、token — 設計時考慮到了安全性。通常是短暫的並且很容易被撤銷。受損的令牌僅具有用戶有權訪問的數據範圍,並且將自動過期。
使用方式#
什麼時候你會使用其中一種而不是另一種呢?看起來他們在利弊之間取得了很好的平衡。
1、API key — 用於伺服器到伺服器之間的通訊,例如訪問天氣 API 等公共數據、與第三方系統集成。
2、token — 用於用戶身份驗證、細粒度訪問控制 (FGAC)、授予對資源的臨時訪問權限、瀏覽器訪問權限以及管理用戶會話。
舉個例子#
現在我們了解了兩者之間的區別,讓我們看一下使用 Momento JavaScript SDK 的兩個實際示例。
API key
上文提到過 API key 通常是在用戶界面創建的。考慮到隱私性,我沒有可以分享的實際 API key。不過以下是大家作為用戶如何通過 Momento 控制台獲取 API 密鑰的方法。
大家可以選擇所需的權限,設置可選的到期日期,然後點擊 Genergate Api Key。然後我們可以在工作流程中使用該 API key。
token
與成功登錄時生成的基於用戶的一次性 token 進行對比。我們可以採用基於角色的示例,用戶可以只讀訪問日曆事件緩存,但可以發布和訂閱協作主題的訪問權限。
// called on successful login
exports.handler = async (event) => {
const user = await loadUserMetadata(event.userId);
let token;
switch(user.role){
case 'data-entry':
token = await getDataEntryToken(user.tenantId);
break;
case 'admin':
token = await getAdminToken(user.tenantId);
break;
default:
throw new Error('Role not supported');
}
return token;
};
const getDataEntryToken = async (tenantId) => {
const scope = {
permissions: [
{
role: 'readonly',
cache: 'calendar-events',
item: {
keyPrefix: tenantId
}
},
{
role: 'publishsubscribe',
cache: 'collaboration',
topic: `${tenantId}-events`
}
]
};
const response = await authClient.generateDisposableToken(scope, ExpiresIn.minutes(15));
return {
token: response.authToken,
expiresAt: response.expiresAt.epoch()
};
};
以在此處看到,我們創建了一個有效期為 15 分鐘的令牌,其權限範圍是日曆功能的只讀權限,並且僅允許訪問以用戶所屬的 tenantId 開頭的緩存項。因此,我們根據用戶的屬性限制了功能和數據。
總結
API key 和 token 各有優缺點。一個並不比另一個更好。在決定要應用哪種身份驗證機制時,請結合你的應用場景來進行選擇。如果是用在用戶會話的身份驗證場景時,可以使用 token。如果是給第三方系統提供接口需要身份驗證時,可以使用 API key。