2

我只是在玩 OpenID 协议。我正在尝试发送 Discovery 请求并从 google 检索 XRDS 文档。当我尝试使用 curl 从终端执行此操作时,我得到以下输出

curl --url "https://www.google.com/accounts/o8/id"
    <?xml version="1.0" encoding="UTF-8"?>
    <xrds:XRDS xmlns:xrds="xri://$xrds" xmlns="xri://$xrd*($v*2.0)">
      <XRD>
      <Service priority="0">
      <Type>http://specs.openid.net/auth/2.0/server</Type>
      <Type>http://openid.net/srv/ax/1.0</Type>
      <Type>http://specs.openid.net/extensions/ui/1.0/mode/popup</Type>
      <Type>http://specs.openid.net/extensions/ui/1.0/icon</Type>
      <Type>http://specs.openid.net/extensions/pape/1.0</Type>
      <URI>https://www.google.com/accounts/o8/ud</URI>
      </Service>
      </XRD>
    </xrds:XRDS>

当我尝试从 ruby​​ 代码中执行相同操作时,它给了我一个 302 错误,并且它移动到的 url 指向相同的请求 url。

<HTML>
<HEAD>
<TITLE>Moved Temporarily</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Moved Temporarily</H1>
The document has moved <A HREF="https://www.google.com/accounts/o8/id">here</A>.
</BODY>
</HTML>

代码

  require 'net/http'
  require 'net/https'
  require 'uri'
  http = Net::HTTP.new(uri.host, uri.port)

  response =  Net::HTTP.get_response(URI.parse("http://www.google.com/accounts/o8/id"))
  puts "#{response.read_body}"

如何通过代码获取 XRDS 以及为什么它显示不同的输出。有人可以解释一下吗?谢谢

4

2 回答 2

3

Google 需要 https 协议,尽管在您的 ruby​​ 示例中您使用 http,因此会出现 302 错误。以下代码段应该为您提供 xrds 文档:

require 'net/http'
require 'net/https'
require 'uri'

uri = URI.parse('https://www.google.com/accounts/o8/id')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
puts "#{response.read_body}"
于 2010-08-18T09:43:37.777 回答
1

如您所见,当您从 ruby​​ 获取文档时,它会返回 302 状态码,这意味着您应该location像 curl 一样查找标题并跟随它。

另一个答案建议只是硬编码有效的网址,但这不是一个正确的解决方案,因为谷歌也可以让它返回 302 并将文档移动到其他地方。

更不用说您应该执行完整的Yadis发现,而不是希望您从 url 获得 XRDS 文档(因为,例如,Google 可能会认为它是解释 OpenID 的好位置,并将 XRDS 移动到其他地方使用X-XRDS-Location标题)。

于 2010-08-18T10:28:25.060 回答