如何使用 OAuth 2.0 实现 Web 小部件

Posted

技术标签:

【中文标题】如何使用 OAuth 2.0 实现 Web 小部件【英文标题】:How to implement a web widget with OAuth 2.0 【发布时间】:2012-10-24 12:47:59 【问题描述】:

我想创建一个 Web 小部件来显示来自我的网站的信息。

该小部件将使用 javascript 包含在客户的网站 html 中,并且应该仅可用于我的客户 -- 在我的网站上注册的网站。

小部件中的信息应特定于当前正在访问客户网站的用户。

因此,我需要对客户端(网站所有者)和资源所有者(网站访问者)进行身份验证。这似乎很好地映射到 OAuth 2.0,但我找不到这种实现的完整示例或解释。

任何资源或指向此类信息的指针将不胜感激。

更新:我偶然发现了this article,它提供了使用 OAuth 的方法的概要。但是,对于我来说,它还不够详细,无法真正理解如何将其与 OAuth 2 一起使用。

【问题讨论】:

"在我的网站上注册的网站" — 您是否假设可以使用 OAuth 进行客户身份验证?还是只为来访者?你是如何创建那个小部件的? (JavaScript,还是客户端服务器上的东西?) 这是我的要求。我需要对客户端和资源所有者进行身份验证。我假设我需要使用 OAuth 2.0 隐式流并将注册的回调 URL 与调用中的 URL 进行比较。但是,这是我正在寻找的解释的一部分...... 那么,假设您使用“网络小部件”这个词和您的earlier post:HTML 中包含一些 JavaScript? (因此:任何客户端令牌都将在 HTML 源代码中可见,并且可能被任何想要在其站点中包含小部件的人滥用?不过我不是专家。) 是的。 HTML 中包含的 Javascript。当然,不应涉及任何客户端机密。这就是 OAuth 2.0 隐式流程的目的。我也不是专家,这就是我问这个问题的原因。 我偶然发现了这篇文章 [supercollider.dk/2009/01/oauth-and-client-side-widgets-154],它提供了使用 OAuth 的方法的大纲。但是,对于我来说,它还不够详细,无法真正理解如何将其与 OAuth 2 一起使用。 【参考方案1】:

有许多大型组织已经这样做了,我很遗憾看到这个问题没有其他答案,因为它是如此重要的网络模式。

我假设你不会从头开始推出自己的 OAuth 2.0 提供程序,如果你这样做了 - 做得好,否则你应该使用像 Doorkeeper 这样的工具来为你做这件事。

现在,在 OAuth 2.0 中,您拥有以下实体:

    在您的网站上注册的用户 在您的网站上注册的应用程序(订阅您的 oauth2) 用户权限,这是用户“允许”的应用程序列表 开发人员(正在使用您的身份验证 API/小部件并构建应用程序)

首先要注意的是您必须拥有与每个应用程序关联的域名。因此,如果开发人员在您的网站上注册 API 令牌/机密,他创建的应用程序将映射到一个唯一域。

现在,我认为应用程序通过您的网站对用户进行身份验证的流程已经很清楚了。话虽如此,您不需要做太多工作。

当应用程序将用户发送到您的网站(以便登录)时,您会在用户的计算机上放置一个会话 cookie。让我们称之为“Cookie-X”。

现在用户已通过您的网站的身份验证并返回到应用程序。在那里,我们想显示一个自定义小部件,其中包含与该用户有关的信息。

开发人员需要将一些代码复制粘贴到此应用中。

流程是这样的:

    该代码将包含一个指向您网站的 URL,其中包含他在您的网站上注册他的应用程序时获得的应用程序 ID(非机密)。

    当该代码运行时,它将使用他的 appId ping 您的网站。您需要使用您的数据库检查该 AppID,并另外检查引荐来源网址是否来自与在您的网站中为该 AppID 注册的域名相同的域。 编辑: 或者或另外,代码可以检查 document.domain 并将其包含在对您网站的 ping 中,允许您验证请求来自已使用给定 AppID 注册的域.

    如果正确,您回复一些 JS 代码。

    您的 JS 代码会查找您的网站在用户登录时设置的会话 cookie。如果找到该 cookie,它会通过会话 ping 回您的网站,并且您的网站会使用自定义视图内容进行响应。

编辑:正如评论中正确提到的,cookie 应该是 HttpOnly 以防止常见的 XSS 攻击。

附加说明

这是一种安全方法的原因:

    AppId 和域名是一个足够好的组合来验证其他人没有获取此信息。即使 appId 在应用程序 html 源代码中可见,域名也必须被任何试图使用其他人的 AppID 的人欺骗。

    假设某人获取了一个不是他的 AppID,并在请求您的小部件时编写代码来欺骗引用者的域名,他仍然无法看到任何信息。由于您正在显示用户特定信息,因此只有当您的网站可以找到它放置在用户浏览器上的会话 cookie 时,小部件才会呈现,而该会话 cookie 不能真正被欺骗。有诸如会话劫持等方法。但我认为这超出了这个问题的范围。

其他方法 只需查看 Facebook 的社交插件,您就可以知道还有其他选择。

例如,可能会使用 iframe。如果你要求开发者在他的应用程序中添加一个 iframe,你甚至可以减少上面提到的一些步骤。但是您必须同时添加 JS(在 iframe 之外)以获取正确的域等。当然,从可访问性和界面的角度来看,我不太了解 iframe。

【讨论】:

“引荐来源网址” -- The article 发现的 OP 使用了 if(document.domain=='the-registered-domain.com') 你为什么要依赖 REFERER? (可能为空。)“您的 JS 代码查找会话 cookie”——这需要 cookie to be NOT HttpOnly。而且,JavaScript 将在开发者的域上运行,并且无法访问会话 cookie?第 4 步和第 5 步不就是一个吗? @Arjan 感谢您指出 httponly - 当时并没有让我印象深刻。我已经添加了。 document.domain vs referrer 不是辩论恕我直言。我都加了。无论如何,我都不想在客户端进行检查,因此 js 可以发送 document.domain 值,在服务器上我们可以检查两者的合法性。哦,我也合并了 4 和 5...长答案在 SO 编辑器中有点乏味。 我不是指合并文本 :-) 相反,我的意思是:JavaScript 如何访问该 cookie,因为它来自不同的域?当 4/5 真的是一个步骤时,我可以理解这是有效的,例如 “您的 JS 代码 ping 网站,这使得浏览器也发送源自您的域的“Cookie-X”。您的服务器检查 cookie并以自定义视图内容进行响应。” 但不是来自 JavaScript 代码?另外,我觉得if(document.domain== ...) 是该链接文章中最重要的细节之一;没有那个代码会在 any 网站上成功吗? 喜欢:在第 1、2 和 3 步中,您不检查 cookie。因此,这可能是带有假 REFERER 的服务器端代码。在第 4 步中,您不检查 if(document.domain== ...)。因此,即使接收到 cookie 表明它是发送请求的实际浏览器,您也不能确定它也是执行前 3 个步骤的浏览器? (我觉得这些正是链接文章解决的缺陷?) 这似乎颇有争议。这是@Arjan 的另一篇相关帖子:***.com/questions/5472668/…。由于我还没有实施任何解决方案,我还不能接受任何解决方案:(

以上是关于如何使用 OAuth 2.0 实现 Web 小部件的主要内容,如果未能解决你的问题,请参考以下文章

用于 REST Web 服务的 OAuth 2.0

如何进行应用程序到应用程序(服务器到服务器)身份验证、OAuth 2.0、Web API 2.0

使用 Laravel API 实现 OAuth 2.0 身份验证

使用 oAuth 对 javascript 小部件进行身份验证

如何使用适用于 Web 服务器应用程序的 Google OAuth 2.0 向 Google ID_Token 添加自定义声明

如何从单页应用程序实现 OAuth 2.0 授权码授予?