深入 XRDS

昨天,我们建立起了一份简单的 XRDS 文档,并利用位于 <head> 中的 <meta> 元素将其植入我们的 Yadis URL 。正常情况下, Yadis URL 应该返回 HTTP 头中所声明的 application/xrds+xml 格式的 XRDS ;但协议同时提到,如果 HTTP 头没有指出位置,而 URL 返回了一个 HTML 文档,那么可以解析 HTML 从中提取 <meta> ,并将 XRDS 返回。这使我们可以十分轻松的在 URL 上实现 Yadis 支持。

XRDS 文档,又称为 Yadis 资源描述文档。它使用 Extensible Resource Descriptor 格式,这一格式由 XRI Technical Committee 开发,并包含进 XRI 解析规范中。
<xrds:XRDS
xmlns:xrds="xri://$xrds"
xmlns="xri://$xrd*($v*2.0)"
xmlns:openid="http://openid.net/xmlns/1.0">
<XRD>
......
</XRD>
</xrds:XRDS>
文档顶层是含有名称空间定义的 <XRDS> 标签,它包含一个或多个 <XRD> 元素,昨天的例子中我们只有一个 <XRD> 。如果有多个,那么最后的一个是可用的,如果一个都没有,这个文档也是有效的,但不含任何的服务。
<Service priority="10">
<Type>http://openid.net/signon/1.0</Type>
<URI>http://www.myopenid.com/server</URI>
<openid:Delegate>http://yourname.myopenid.com/</openid:Delegate>
</Service>
在 <XRD> 中,服务由 <Service> 来描述。一个 <Service> 至少有一个 <Type> 元素,定义服务类型。同时根据不同的服务,还有其他各种标签来提供进一步的信息。可以看到上面的例子,是定义一个 1.0 的 OpenID ,在 OpenID 中,这一方式也叫委派。

至此,我们花费了十几行代码,才实现了过去流行的在 HTML 中使用两个 <link> 标签在个人域名上向外委派 OpenID 的功能。但这是值得的,因为你很快注意到位于 <Service> 中 priority 的这个属性。

这是一个重要的属性, priority 用来指定某个服务的优先级。我们可以用它来实现一些实用的特性。先看一个 MyOpenID 的标准 <XRD> 节。
<Service priority="0">
<Type>http://specs.openid.net/auth/2.0/signon</Type>
<Type>http://openid.net/sreg/1.0</Type>
<Type>http://openid.net/extensions/sreg/1.1</Type>
<Type>http://schemas.openid.net/pape/policies/2007/06/phishing-resistant</Type>
<Type>http://openid.net/srv/ax/1.0</Type>
<URI>http://www.myopenid.com/server</URI>
<LocalID>http://yourname.myopenid.com/</LocalID>
</Service>

<Service priority="1">
<Type>http://openid.net/signon/1.1</Type>
<Type>http://openid.net/sreg/1.0</Type>
<Type>http://openid.net/extensions/sreg/1.1</Type>
<Type>http://schemas.openid.net/pape/policies/2007/06/phishing-resistant</Type>
<Type>http://openid.net/srv/ax/1.0</Type>
<URI>http://www.myopenid.com/server</URI>
<openid:Delegate>http://yourname.myopenid.com/</openid:Delegate>
</Service>
priority 的值是一个数字,越小说明优先级越高。这里用 0 和 1 分别将 2.0 和 1.1 的 OpenID 都描述下来,这样这个 OpenID URL 就可以在实施不同版本的网站上进行登录,而不会像 Yahoo! OpenID 那样在 1.0 的网站上失败。注意看这里两个 <Service> 的 <Type> 是不同的,如果我们描述两个相同的 <Type> 呢?
<Service priority="10">
<Type>http://openid.net/signon/1.0</Type>
<URI>http://www.myopenid.com/server</URI>
<openid:Delegate>http://yourname.myopenid.com/</openid:Delegate>
</Service>

<Service priority="20">
<Type>http://openid.net/signon/1.0</Type>
<URI>http://www.livejournal.com/openid/server.bml</URI>
<openid:Delegate>http://yourname.livejournal.com/</openid:Delegate>
</Service>
这是两个 1.0 OpenID 的描述,聪明的你应该想到了它的作用。网站在解析出这个 XRDS 文档后,发现两个一样的服务,于是它先使用优先级高,也就是 priority 值小的那个,如果第一个服务失效了,那么网站会沿着优先阶梯继续发出请求,直到成功为止。利用 priority ,我们很好的解决了上次 MyOpenID 离线引发的问题而不用担心网站端是否支持绑定多 OpenID 。

由优先级属性引起的第三个附加作用,是负载平衡。如果多个相同的服务被指定相同的优先级, Yadis 规定其中一个将被随机的选中。如果这一技巧频繁出现在将来的 XRDS 中,那说明 OpenID 已经产生显著的影响力了,因为截至目前, OpenID 仍是 Yadis 中使用的最多的服务。

盘弄一下你的 XRDS ,然后休息一下,看看接下来我们还能做些什么。

没有评论:

发表评论

挨踢 (63) 月月梳 (2) 杂文 (57) 诗歌 (34)