本文内容来自 Authing 开发者杨恒。
我虽然不是安全专家,但是实现过一些不同的身份认证系统,我遇到了很多挑战,我花费了很多时间弄清楚如何把这件事做的更好。幸运的是,我发现了一些做身份管理和身份认证的 SaaS 平台,有时也被称为 IDaaS 服务。我非常建议用这类服务,而不是自己构建身份认证解决方案。
身份认证是通过使用用户名、密码等登录方式来验证用户身份的过程。授权是通过使用用户组、角色和权限等来验证用户是否有资源访问权限的过程。这些基于云的身份认证提供商除了提供了这些基础功能外还有很多其他拓展性功能。
有很多 IDaaS 服务商可以选择,但是在本文,我将重点介绍我个人熟悉的两个提供商。一个是美国的 Auth0,另外一个是中国的 Authing,这两家提供商都是提供面向消费者的身份认证服务,同时是开发者友好的。
为什么 IDaaS 能够 Make sense
API 驱动的身份认证云的出现,让我们摆脱了必须自己建立完整的身份认证和授权系统的麻烦。用户系统具有高度动态性,因为它们经常更改,并且也是恶意流量的最大目标。建立我们自己的用户系统不仅复杂且耗时,而且会有潜在的安全问题。通过使用 IDaaS,我们可以减少开发时间和麻烦,同时还可以确保我们的系统由行业专家构建和保护。
Auth0 和 Authing 都允许开发者快速解决身份认证问题,同时可以让用户在最短的时间内注册并登录我们的应用程序。除了最简单的使用方法外,它们都允许通过 SDK 完成多种身份认证策略。
嵌入式身份验证解决方案
API 驱动的身份认证云的出现,让我们摆脱了必须自己建立完整的身份认证和授权系统的麻烦。用户系统具有高度动态性,因为它们经常更改,并且也是恶意流量的最大目标。建立我们自己的用户系统不仅复杂且耗时,而且会有潜在的安全问题。通过使用 IDaaS,我们可以减少开发时间和麻烦,同时还可以确保我们的系统由行业专家构建和保护。
Auth0 提供了两种嵌入式解决方案。第一个是名为 Lock 的登录小部件,其拥有很多的自定义选项,例如添加自定义注册字段的功能,然后将其保存到用户的元数据中,这非常好。第二个是 Auth0 提供的二级域名登录页面,该页面允许我们自定义样式。Auth0 Lock 小部件非常易于集成,代码如下所示:
<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 在注销时被销毁了。
总体而言,使用 Auth0 进行有效 API 调用所需的时间是 9 分钟,还不错!
使用 Authing 进行首次 API 调用的时间
我运行了 Authing 官方的 Web SSO Sample,在注册了 Authing 账号和和创建了一个应用后,然后把相关信息填入了代码中。
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 调用的时间是五分钟,非常棒!
开发体验
使用标准的认证流程必须要理解什么是 OAuth 流程,从 API 和文档的角度来看,Auth0 和 Authing 都有相当清晰简洁的文档,可以帮助你选择最合适的流程。不过,总的来说,Authing 的文档要好一些,有清晰的解释和详细的图表。比如,Authing 有两页文档介绍了 OAuth 2.0。
社交登录集成
现在,我使用了 OAuth 2.0 流程来处理用户认证,但是我还需要添加社交登录。
不用想都知道,Auth0 和 Authing 都提供了社交登录方案。Auth0 和 Authing 提供的方案并无太大的差别,都是通过控制台配置然后在 Lock 部件或者 Guard 部件中可以自动加载出来,两者在配置过程中都不需要写任何代码。
Auth0 的社交登录集成的比 Authing 多,但是对于中国人来说,Authing 集成了很多 Auth0 没有集成的中国社交登录,甚至还包含小程序扫码登录。
Auth0
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 也有集成国内企业级软件的优势。
文档和资源
研究新产品的第一步通常是阅读其文档。这就使服务商必须提供出色,详细和简洁的文档。
Auth0 和 Authing 的文档都非常全面,但是 Auth0 的文档比 Authing 多了更多可交互的功能,这是 Authing 所不具备的。
结论
我研究了中美两国两个领先的 IDaaS 解决方案的功能,在此过程中,我还对他们的工作原理有了更深入的了解。对我来说,很明显 Authing 要比 Auth0 更加本地化,更适合中国人。其产品还有精美的设计,作为前端开发者,我很喜欢。
总体而言,两种解决方案都可以完成工作,但是我更喜欢 Authing,因为它更优雅且更简单,集成所用的时间也更少。