概述:身份验证已经够难了。请务必了解两种主要身份验证模式之间的区别:API密钥和令牌。
他们说,计算机科学中最困难的两个问题是缓存失效和命名。老实说,这并没有错。这些都非常困难。
让命名变得困难的是清晰而简洁。变量、术语、函数或类的含义应该是毫无疑问的。如果您认为某个术语可能意味着两件事之一,那么它的名称不正确。
API 密钥和令牌就是这种情况。前几天我在一次讨论中,这两个词被互换使用。大约两分钟后,我不得不停止谈话并说:“你知道这些是不同的,对吧?
显然他们不知道。事实证明,很多人无法告诉我 API 密钥和令牌之间的区别。因此,让我们直截了当地记录。
定义
我们可以通过以下定义来区分 API 密钥和令牌:
- API 密钥 — 调用 API 以识别和授权调用方时_由代码_提供的值。它旨在以编程方式使用,通常是一长串字母和数字。
- 令牌 — 表示用户会话或特定权限的一段数据。个人用户在有限的时间内使用。
Generation
两者之间的创建方法通常也不同。
- API 密钥 — 创建一次,通常通过用户界面创建,在轮换之前保持静态。可以选择将其配置为在一定时间后过期。
- 令牌 — 在身份验证或登录事件成功时动态生成。通常过期时间较短,但可以刷新较长时间。
范围
如果不讨论权限范围,就不会讨论身份验证。
通过权限范围,我指的是授权部分或使用提供的身份验证方法时可以执行的功能。
- API 密钥 — 对应用功能的固定、不变的权限集。拥有密钥的人都可以访问允许的资源。
- 令牌 — 仅限于个人有权访问的特定数据或功能。这可能会受到角色或其他业务级别要求的影响。往往更关注数据限制。
安全
每种方法的安全性如何?如果密钥或令牌被恶意用户泄露或获取,潜在损害有多严重?
- API 密钥 — 由于这些密钥通常存在很长时间,并且不会限制对数据的访问,因此如果遭到破坏,它们可能会造成毁灭性的影响。它们要求撤销密钥作为唯一的解决方式。应用程序通常需要具有良好的可观测性,以识别泄露的密钥并找到恶意用户。
- 令牌 — 在设计时考虑到了安全性。通常寿命很短,很容易被撤销。被泄露的令牌将仅具有用户有权访问的数据范围,并将自动过期。
使用案例
那么,你什么时候会使用一个而不是另一个呢?看起来他们在利弊之间取得了很好的平衡。
- API 密钥 — 用于服务器到服务器的通信,访问公共数据(如天气 API),与第三方系统集成。
- 令牌 — 用于用户身份验证、细粒度访问控制 (FGAC)、授予对资源的临时访问权限、浏览器访问权限和管理用户会话。
例子
现在我们了解了两者之间的区别,让我们看两个使用 Momento JavaScript SDK 的实际示例。
API密钥
我确实说过,API密钥通常是通过用户界面颁发的。考虑到这一点,我没有代码示例可以共享。
但是,以下是您作为用户通过 Momento 控制台获取 API 密钥的方法。
您将选择所需的权限,设置可选的到期日期,然后生成。然后,您可以立即在工作流中使用 API 密钥。
令 牌
与此形成鲜明对比的是,成功登录时颁发的基于用户的一次性令牌。
我们可以举一个基于角色的示例,该用户对 calendar-events 缓存具有只读访问权限,但发布和订阅对主题的访问权限以进行协作。
// 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 密钥和令牌各有利弊。一个并不比另一个好。与计算机科学中的所有事情一样,这取决于您的用例。在决定要实现哪种身份验证机制时,请考虑用户将如何与应用程序交互。
是网络上基于用户的会话吗?使用令牌。也许你期望仅以编程方式访问,而无需确定可用数据的范围。使用 API 密钥。请随时将我们的参考表保存在顶部,以便快速参考。
无论您采取哪种方式,请记住确保您的数据安全。