10

为什么你会做一个自动的 HTML 帖子而不是一个简单的重定向?

这样开发人员可以在知道 OpenID 时自动生成将目录发布到远程服务器的登录表单吗?

例如。

  1. 用户未登录并访问您的登录页面。
  2. 您从 cookie 中检测到用户的 openID。
  3. 生成的表单直接发布到远程 OpenID 服务器。
  4. 远程服务器将用户重定向回网站。
  5. 网站登录用户。

如果是这种情况,我可以看到好处。但是,这假设您在用户注销时将用户的 openID 保存在 cookie 中。

我几乎找不到关于如何最好地实施这个规范的信息。

请参阅官方规范中的 HTML FORM 重定向:

http://openid.net/specs/openid-authentication-2_0.html#indirect_comm

我通过查看PHP OpenID 库(版本 2.1.1)发现了这一点。

// Redirect the user to the OpenID server for authentication.
// Store the token for this authentication so we can verify the
// response.

// For OpenID 1, send a redirect.  For OpenID 2, use a Javascript
// form to send a POST request to the server.
if ($auth_request->shouldSendRedirect()) {
    $redirect_url = $auth_request->redirectURL(getTrustRoot(),
                                               getReturnTo());

    // If the redirect URL can't be built, display an error
    // message.
    if (Auth_OpenID::isFailure($redirect_url)) {
        displayError("Could not redirect to server: " . $redirect_url->message);
    } else {
        // Send redirect.
        header("Location: ".$redirect_url);
    }
} else {
    // Generate form markup and render it.
    $form_id = 'openid_message';
    $form_html = $auth_request->htmlMarkup(getTrustRoot(), getReturnTo(),
                                           false, array('id' => $form_id));

    // Display an error if the form markup couldn't be generated;
    // otherwise, render the HTML.
    if (Auth_OpenID::isFailure($form_html)) {
        displayError("Could not redirect to server: " . $form_html->message);
    } else {
        print $form_html;
    }
}
4

3 回答 3

7

我能想到几个原因:

  • 默默无闻的一点安全性 - 篡改 POST 提交的工作比 GET 稍多一些
  • POST 的缓存和重新提交规则比 GET 更严格。不过,我不完全确定这对 OpenID 用例是否重要。
  • 机器人不会遵循 POST 表单,但会遵循重定向。这可能会影响服务器负载。
  • 不同的浏览器对 GET 请求有不同的最大长度 - 但它们都没有 POST 那样大。
  • 某些浏览器会在重定向到另一个域时发出警告。如果您将 POST 提交到非 HTTPS 网址,它们也会发出警告。
  • 通过关闭 JavaScript,我可以获得相对安全的体验,而不会被无声地重定向到另一个域。

我不知道其中任何一个都是选择 POST 的灌篮理由——除非发送的数据量超过某些主要浏览器的查询字符串长度。

于 2008-08-30T13:47:51.220 回答
6

正如 Mark Brackett 所说,主要动机是使用重定向和 GET 对有效负载大小施加的限制。一些实现足够聪明,只在消息超过一定大小时才使用 POST,因为 POST 技术肯定有缺点。(其中最主要的事实是您的后退按钮不起作用。)其他实现,例如您引用的示例代码,为了简单性和一致性而忽略了那个条件。

于 2008-09-17T17:48:25.357 回答
4

SAML Web 浏览器 SSO 配置文件使用相同的方法。使用 HTML Post 重定向的主要动机是:

  • 有效负载的长度几乎不受限制:在 SAML 中,有效负载是使用 XMLDSig 签名并经过 base64 编码的 XML 文档。它大于 URL 通常的 1024 个字符限制(不仅支持任何浏览器,还支持防火墙、反向代理、负载均衡器等中间网络设备的最佳实践)。

  • W3C HTTP 标准说 GET 是幂等的(多次执行相同的 URL GET 应该总是产生相同的响应),因此可以一路缓存,而 POST 不是并且必须到达 URL 目标。不应缓存 OpenID HTML 表单 POST 或 SAML HTML 表单 POST 的响应。它必须到达目标才能启动经过身份验证的会话。

您可能会争辩说,使用 HTTP GET 重定向也可以,因为 URL 查询总是会发生变化,而且您的做法是正确的。然而,这将是 W3C 标准的一种解决方法,因此,只要双方都同意,它不应该是标准,而是替代实现。

于 2009-03-21T13:26:16.757 回答