Skip to content

原生应用可以在没有 Client Secret 的情况下使用授权码流程,这是完全可以且推荐的做法。(1)(2)

为什么原生应用不需要 Client Secret

原生应用属于公共客户端(Public clients),具有以下特征:(1)

原生应用是安装并在资源所有者的设备上执行的。协议数据和凭据可以被资源所有者访问。通常假定应用程序中包含的任何客户端身份验证凭据都可以被提取出来。(1)

由于这个原因:(1)

  • 单页应用(SPA)和原生应用是公共客户端
  • 在 Logto 中创建 SPA 或原生应用时,没有 App secret
  • 这是因为公共客户端的密钥无法保证安全

有和没有 Client Secret 的区别

对于公共客户端(原生应用、SPA)

在 Logto 中:(2)

对于公共客户端,客户端凭据通常硬编码在客户端,例如在 JavaScript 包或原生平台的应用程序包中。与机密客户端相比,由于客户端凭据在客户端代码中的固有暴露,凭据泄露的风险更高。在令牌交换流程中,提供 Client Secret 是可选的。Logto 默认不会信任来自公共客户端的这些凭据。(2)

对于机密客户端(传统 Web 应用)

相比之下:(2)

对于机密客户端,所有授权相关的凭据(包括客户端凭据)都安全地存储在服务器端。此外,所有中间交换请求都经过加密以确保数据的机密性。机密客户端的客户端凭据泄露风险非常低,使其本质上更安全。因此,机密客户端默认被视为更高的安全级别。在令牌交换流程中,提供 Client Secret 是必需的(2)

原生应用的安全保障:PKCE

由于公共客户端无法安全存储 Client Secret,OAuth 引入了 PKCE(Proof Key for Code Exchange) 来解决这个问题:(2)

PKCE 通过在每个授权流程开始时临时生成一个 code verifier 来解决这个问题,该 verifier 存储在本地并经过哈希处理生成 code challenge,然后发送到授权服务器。在交换访问令牌时,code verifier 会再次发送到授权服务器。授权服务器验证 code verifier 和 code challenge 是否匹配,这确保公共客户端没有被冒充。(2)

PKCE 中的 code verifier 实际上充当动态的客户端密钥。其安全性由哈希算法的不可逆性来保证。(2)

OAuth 2.1 的要求

在 OAuth 2.1 中,这一点得到了进一步强化:(3)

OAuth 2.1 中最重要的变化之一是,对于所有使用授权码流程的 OAuth 客户端,PKCE 现在是强制性的。PKCE 是一个安全扩展,可以防止授权码拦截攻击。它对于无法安全存储客户端密钥的移动应用和单页应用(SPA)特别有用。(3)

在 Logto 中,带 PKCE 的授权码流程是所有 SPA 和移动应用支持的唯一流程。授权码流程通过交换授权码提供了一种更安全的方式来获取访问令牌。(3)

总结:原生应用不仅可以在没有 Client Secret 的情况下使用授权码流程,而且必须使用 PKCE 来确保安全性。PKCE 替代了 Client Secret 的作用,为公共客户端提供了同等甚至更强的安全保障。

/src/technology/dateblog/2026/04/20260411-logto%E7%9A%84client-secret%E5%92%8Cpkce.html