我正在玩OpenID协议。我正在尝试发送Discovery请求并从谷歌检索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错误,并且它移动的网址指向同一个请求网址。
<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,为什么它显示不同的输出。有人可以解释一下吗?谢谢
答案 0 :(得分: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}"
答案 1 :(得分:1)
正如您所看到的,当您从ruby中获取文档时,它会返回302状态代码,这意味着您应该查找location
标题并按照它进行操作,就像curl一样。
另一个答案建议只是对有效网址进行硬编码,但这不是一个正确的解决方案,因为Google也可以将其返回302并将文档移动到其他位置。
更不用说您应该执行完整的Yadis发现,而不是希望您从网址获取XRDS文档(因为,例如,Google可能会认为它是解释OpenID的好位置,并使用X-XRDS-Location
标题将XRDS移动到其他位置。