本文翻译自国外论坛 medium,原文地址:https://medium.com/momento-serverless/api-keys-vs-tokens-whats-the-difference-b3358b664ea6
“计算机科学只存在两个难题:缓存失效和命名。” — Phil KarIton
命名的难度在于如何让变量、常量、函数或类的定义清晰而简洁,而不应有歧义。如果我们不能清楚的看懂某个变量,那么这个变量的命名就不太准确。
API key 和 token 就有这种问题,它们都是作为一种身份验证机制。前几天我在一次讨论中,有人提到这两个词可以互换使用。大约两分钟后,我不得不停止谈话并说“你们应该知道它们是不同的,对吧?”,说完会上鸦雀无声,显然他们不知道。事实证明,很多人都无法告诉我 API key 和 token 之间的区别。因此文本我将向大家介绍它们之间的区别。
我们可以通过以下定义来区分 API key 和 token。
两者之间的创建方法通常也不同。
权限范围是指授权部分或使用提供的身份验证方法时可以执行哪些功能。
它们的安全性如何?如果 API key 或者 token 被恶意用户泄露或获取,潜在的损害有多严重?
什么时候你会使用其中一种而不是另一种呢?看起来他们在利弊之间取得了很好的平衡。
现在我们了解了两者之间的区别,让我们看一下使用 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。
·END·