当使用 Serverless 开发应用程序时,我一直在探索无服务器身份认证的可能性,当我对比了 Auth0 和 Authing 后非常激动:我发现自己需要做的工作非常少,而且可以解决很多麻烦!
我虽然不是安全专家,但是实现过一些不同的身份认证系统,我遇到了很多挑战,我花费了很多时间弄清楚如何把这件事做的更好。幸运的是,我发现了一些做身份管理和身份认证的 SaaS 平台,有时也被称为 IDaaS 服务。我非常建议用这类服务,而不是自己构建身份认证解决方案。
身份认证是通过使用用户名、密码等登录方式来验证用户身份的过程。授权是通过使用用户组、角色和权限等来验证用户是否有资源访问权限的过程。这些基于云的身份认证提供商除了提供了这些基础功能外还有很多其他拓展性功能。
有很多 IDaaS 服务商可以选择,但是在本文,我将重点介绍我个人熟悉的两个提供商。一个是美国的 Auth0,另外一个是中国的 Authing,这两家提供商都是提供面向消费者的身份认证服务,同时是开发者友好的。
为什么 IDaaS 能够 Make sense
API 驱动的身份认证云的出现,让我们摆脱了必须自己建立完整的身份认证和授权系统的麻烦。用户系统具有高度动态性,因为它们经常更改,并且也是恶意流量的最大目标。建立我们自己的用户系统不仅复杂且耗时,而且会有潜在的安全问题。通过使用 IDaaS,我们可以减少开发时间和麻烦,同时还可以确保我们的系统由行业专家构建和保护。
Auth0 和 Authing 都允许开发者快速解决身份认证问题,同时可以让用户在最短的时间内注册并登录我们的应用程序。除了最简单的使用方法外,它们都允许通过 SDK 完成多种身份认证策略。

<html><head> <title>Example Auth0 Sign-In Widget</title></head><body> <script src='https://cdn.auth0.com/js/lock/10.24.1/lock.min.js'></script> <script> const lock = new Auth0Lock('$AUTH0_LOCK_SECRET', 'rbin.eu.auth0.com', { auth: { redirectUrl: 'http://localhost:3000/auth/auth0/callback', responseType: 'code', params: { scope: 'openid email' // more about scopes: https://auth0.com/docs/scopes } } })</script> <button onclick='lock.show()'>Login</button></body></html>
Authing 也有两种可用的嵌入式解决方案:二级域名标准登录页面(由 Authing 托管的重定向身份认证解决方案)和其名为 Guard 的登录小部件,Guard 也提供了功能强大的登录解决方案和大量自定义选项。
Authing 登录小部件可以轻松添加到任何 Web 应用程序中,代码如下所示:
<html><head> <title>Example Authing Sign-In Widget</title></head><body> <script src='https://cdn.jsdelivr.net/npm/@authing/sso/dist/AuthingSSO.umd.min.js'></script> <script> const authing = new AuthingSSO({ appId: "5d70d0e991fdd597019df70d", appDomain: "sample-sso.authing.cn" })</script> <button onclick='authing.login()'>Login</button></body></html>
从代码中可以明显看到,Authing 的初始化要比 Auth0 简单很多。
使用 Auth0 进行首次 API 调用的时间
通过运行 Auth0 的 Node.js 快速入门教程,我进入了基本的 Web 应用程序的登录页面。注册免费的 Auth0 帐户后,我在其管理控制台中创建了标准 Web 客户端,并将客户端 ID和 Secret 复制到我的应用程序的变量中:
{ "AUTH0_CLIENT_ID": "$AUTH0_CLIENT_ID", "AUTH0_DOMAIN": "$AUTH0_ACCOUNT_DOMAIN.eu.auth0.com", "AUTH0_REDIRECT_URL": "http://localhost:3000"}
使用 Auth0 Web Auth 模块的代码非常简单,因为只需要将授权详细信息存储到本地存储中:
const webAuth = new auth0.WebAuth({ domain: sampleConfig.AUTH0_DOMAIN, clientID: sampleConfig.AUTH0_CLIENT_ID, redirectUri: location.href, audience: `https://${ sampleConfig.AUTH0_DOMAIN }/userinfo`, responseType: 'token id_token', scope: 'openid', leeway: 60})function setSession(authResult) { const expiresAt = JSON.stringify( new Date().valueOf() + authResult.expiresIn * 1000 ) localStorage.setItem('access_token', authResult.accessToken) localStorage.setItem('id_token', authResult.idToken) localStorage.setItem('expires_at', expiresAt)}
运行 Web 应用程序,我们可以在下图中看到会话详细信息存储在本地存储中。编码的 JWT id_token 以红色突出显示。我们还可以观察到 Session 在注销时被销毁了。

const authing = new AuthingSSO({ appId: "5d70d0e991fdd597019df70d", // OIDC 应用的 ID appType: "oidc", // SSO 类型为 OIDC 类型 appDomain: "sample-sso.authing.cn" });const callTrackSession = async function() { const res = await authing.trackSession(); if (!res.session) { console.log('未登录'); }else { console.log(res); }};callTrackSession()
在运行且登录成功后,我看到控制台打印出了如下信息:


Authing
API 调试
Auth0 和 Authing 的 API 调试方式不太一样,Auth0 是标准的 RESTful API,而 Authing 使用了 GraphQL。
RESTful API 相比 GraphQL 更容易调试,Authing 为了解决 GraphQL 难调试的问题,他们做了一款在线调试 Authing GraphQL 的工具,如下所示:
从图中可以看到,Authing 几乎开放了所有 GraphQL 的描述和访问权限。
从这一点来看,很难说谁好谁坏,如果从易用性角度来看,Auth0 更胜一筹。
可扩展性
Auth0 十分注重可扩展性,并提供了一个平台来赋予 Auth0 顶级的可拓展性: Auth0 Extend。这个平台专注于无服务器后端,Extend 可在极短的时间内部署代码片段。 相比之下,Authing 还没有这样的函数计算平台来做插件化,不过其文档中有表明此类平台正在研发。
OpenID 和 SAML
OpenID Connect(OIDC)是基于 OAuth 2.0 系列规范的身份认证协议。它使用通过OAuth 协议提供的 JWT 令牌,其目的是使用户能够跨多个站点使用一个登录名。同样,两家提供商都为此提供了解决方案。 这两个平台的 SAML 模块都可以用作服务提供商(SP)和身份提供商(IdP),但是从文档角度来看, Auth0 具有大量的 SAML 文档,而 Authing 的 SAML 文档较为稀缺。不过 Authing 也有集成国内企业级软件的优势。