金牌译作 如何让你的网站也支持OpenID(二)

1128个读者 翻译: deng  01/19/2008 原文 引用 双语对照及眉批 字体大小

实现细节
1.安装一个OpenID用户库
  • 目前已经有很多流行编程语言的OpenID库,它们替你解决了绝大部分的负担。
  • 在库的基础上,你需要建立和提供者网站之间的联系,实质上,就是建立把服务和处理器处理成连接字符串。你至少需要把这种联系存储在session中,用来验证一个OpenID的授权,但比较完美的情况还是你长期存储他们,这样就不用每次重定向到OpenID提供者时都重新建立他们之间的联系。你可以用 memcached、数据库或者其他你能访问到的存储介质。
2.创建一个OpenID数据表
  • 你可以使用下面的schema:
  • create table user_openids (
  •   openid_url varchar(255) not null,
  •   primary key (openid_url),
  •   user_id int not null,
  •   index (user_id)
  • );

  • 保持一个单独的全局表,这样你就能通过OpenID找到所有的用户(即使你的用户信息分布在多个数据库中)
  • 存取OpenID URL在一个规范化映射表,可以使查找更加健壮(也就是说如果用户下次输入的OpenID有一些细微的差别,你同样可以映射到他的账户)。大部分 OpenID库将提供纠错的功能,不过你还是应该在缺少http://时毫不犹豫地加上去,另外,应该把协议和域都变成小写(但不包括剩下的部分)。比如 "WWW.AOL.Com/myOpenID",应该变成http://www.aol.com/myOpenID。你应该把URL后面多余的/也去掉。
  • 如果你经常使用数据访问层的代码,你应该把下面的函数提供给程序(在每个函数下边我都提供了对应的sql语句)。还要提醒一下,所有用OpenID作为参数的函数都需要提前纠错一下。

    * GetUserId(openid_url)
      select user_id from user_openids where openid_url = openid_url
    * GetOpenIDsByUser(user_id)
      select openid_url from user_openids where user_id = user_id
    * AttachOpenID(openid_url, user_id)
      insert into user_openids values (openid_url, user_id)
    * DetachOpenID(openid_url, user_id)
      delete from user_openids where openid_url = openid_url and user_id = user_id
    * DetachOpenIDsByUser(user_id)
      delete from user_openids where user_id = user_id
2.添加OpenID的内容到注册页面
  • 添加内容使得OpenID用户可以通过OpenID登陆。这部分UI的目标是是OpenID用户很容易识别你的网站支持OpenID,但非OpenID用户又不会因此感到迷惑。你可以添加一个OpenID输入框或者一个到可以输入OpenID的页面的链接。
  • 无论你放到哪,你都必须使输入框符合OpenID的命名规范:
  • 使用“openid_url”作为文本框的id和name属性(这将能使插件更加容易识别和处理来自不同网站的OpenID的输入框)。
  • 添加小OpenID logo作为输入框的北京,使用类似的css样式:
    background: #FFFFFF url('/images/openid-icon-small.gif') no-repeat scroll 0pt 50%;
    padding-left: 18px;
  • 如果提供对OpenID的介绍以及在你的网站如何使用它的简短说明,将会是个不错的注意,这样能吸引那些好奇的人过来一探究竟。
  • 将输入框放入到一个form中,设置form的action为处理OpenID的页面,接下来我们就着手建立这样的页面。
  • 在提供了OpenID并在OpenID提供者登陆以后,用户将返回到注册页面,这里有两个需要注意的地方。第一,你应该显示该用户注册的OpenID,把小OpenID logo放在后面会更好。第二,你不应该再次要求用户输入在你的网站的密码,因为他们将通过OpenID直接登陆。所以需要吧密码框隐藏起来,并确保你的代码能允许这样(如果你的程序一定要求要有密码的话,你可以生成一些随机字符串,只不过不让用户看到而已)。请注意:也可以在帐户设置页面让用户输入一个你网站的密码,不过需要注意使用OpenID的最大好处是用户不用再维护他们在各个网站不同的注册信息。
3.添加OpenID相关内容到登陆页面
  • 添加OpenID用户登陆的内容到登陆页面。这对已经注册并绑定了OpenID的用户和用OpenID注册的新用户都是有用的。想注册页面一样,UI的设计目标是需要保持非OpenID用户和OpenID用户之间的平衡。你应该使OpenID输入框的命名和样式和注册页面保持一致。包围输入框的form也应该只想你将创建的动态页面。
  • 在网站其他任何有传统登陆方式的地方,你都应该增加OpenID的登陆方式。
4.创建一个OpenID登陆的动态页面
  • 必须提供两个基本的访问参数给动态页面
  • openid_url:用户指定的OpenID,包括注册、登陆、绑定等。
  • action_type:用户要采用的操作类型。这个参数的只有可能是login、complete、attach、list和delete。(如果你用Rails或者类似的体系,这些可能是一个控制器方法或者url本身的一部分)
  • 实现login动作(这是在注册和登陆流程里边都要提交到的地方)
  1. 用上文提到的GetUserId函数获取openid_url。
  2. 如果OpenID已经被你网站的用户绑定过了,检查这个用户是不是已经在你的网站登陆了。
  1. 如果这个用户还没有登陆,则用户是试图用这个帐号登陆,所以需要准备重定向到对应的OpenID提供者,但是需要设置一个标记表明不是用来注册。
  2. 如果用户已经登陆了,而且这个OpenID属于用户(也就是说,这个OpenID的URL已经关联到这个登陆用户的user_id),你就不需要做任何事情(这个用户已经登陆而且已经绑定了这个OpenID,所以这是相当于没操作),这是一个特殊情况。
  3. 如果这个用户已经登陆了,但OpenID属于另一个用户,则提示这个账户已经被另外的用户绑定过了。你同事可以提供注销和再试一次的选项。这是另一种特殊情况。
如果这个OpenID还没有存在你的数据库中,那么这个用户是尝试用它注册新帐户,把页面重定向到OpenID提供者并请求注册信息即可。保存openid_url在session,因为当OpenID提供者返回时有可能并不返回这个值给你。如果你的网站不支持session,你可以使用数据库,但最重要的是这个保存的地方不能收到用户的干预(比如cookie或者可以被用户改变或“杜撰”内容的地方)。(需要你保存请求的OpenID是因为OpenID允许用户使用其他网站的代理。举例来说,如果我视图用OpenID josephsmarr.com来登陆,我可能会用选择另一个OpenID jsmarr.myopenid.com作为代理,当提供者验证完毕返回时,你需要记住我是想用josephsmarr.com登陆而不是jsmarr.myopenid.com。幸运的是,大多数OpenID库已经处理这个问题了,但是你还是需要保存原始请求的OpenID在session里边。这种问题有可能在OpenID2.0中得以解决。)用户验证通过后的返回地址参数return_to需要由这个动态页面提供,这个页面将用来处理complete动作。如果你判断用户准备注册一个新帐户,就需要确定他提供哪些额外的注册信息。大部分的OpenID提供者都支持这些简单注册内容,这些信息是一些通用的内容,包括姓名、email、昵称、性别、生日、邮政编码、国家、语言以及时区,你可以随取所需,从而减少注册流程的时间以及一些额外的负担。如果你的OpenID用户库并不支持对简单注册参数的请求,可以看看库是不是提供对扩展的支持,即使是最坏的情况,你也可以在重定向之前添加请求参数到转发地址。调用OpenID库中checkid_setup函数产生OpenID提供者的地址。需要传递给OpenID提供者用户名和第5步创建的返回地址,另外,还有你想获取的简单注册信息的相关参数。你可能需要获取和处理这个函数的某些错误,但如果假定一切OK的话,你将得到需要重定向的地址。通过发出服务器端的重定向应答,让动态页面重定向到上面获取的地址。用户将会被重定向到OpenID提供者的网站,他们需要登陆(除非已经登陆过了),然后需要决定是否新人你的网站,如果有注册信息请求的话,也需要决定共享哪些信息给你。如果他们完成了这些过程,OpenID提供者将会把页面转到你提供的return_to所指向的URL地址,然后你将启用你的complete动作完成整个处理流程了。实现complete动作(当用户已经登陆OpenID提供者的网站并返回的时候)
  1. 当OpenID提供者返回到你的return_to地址时,他们会在地址上添加一些用来验证用户授权信息的请求参数。通过你使用的OpenID库,你可能需要收集这些信息为指定的数据结构,用来通过验证函数,也有可能它自己就帮你做好这些事情了。
  2. 从session中获取用户最初请求的OpenID。
  3. 调用OpenID库中的id_res来验证你发给OpenID提供者的授权数据。传给用户请求的原始OpenID,以及一些必要的请求参数。这个函数将检查是不是一切都有效。如果它返回错误信息,给用户提示适当的一些信息;否则你就可以正式确认这个用户的合法性了。
  4. 在验证成功后,你也可以在你的网站给这个OpenID设置一个永久的cookie,下次这个用户进入网站的时候就可以在OpenID输入框预先填充好这个OpenID了。如果这样做的话,需要确保当用户注销时清除掉这个cookie。
  5. 用GetUserId函数重新获取验证过的OpenID。如果你不能从数据库中获取,检查用户是不是这会已经登陆了。如果是,执行attach动作绑定OpenID到用户已经存在的帐号。否则,是时候启动注册进程创建一个使用改OpenID的新帐户了。保存OpenID到session,这样账户创建的代码将能确保这个用户已经验证过这个OpenID了。(不要使用存取请求过的OpenID的session变量了,因为用户可以输入任何内容给那个变量)然后将用户重定向到注册流程,并填充你获取的简单注册信息(如果有的话),因此你需要想办法把返回的这些注册信息和你网站平常使用的注册信息关联起来。
  • 像上面所描述的一样,注册页面应该非常显著地显示OpenID,并且不要在此要求用户为你的网站输入密码,因为他们已经使用OpenID登陆了。另外,你应该把从OpenID提供者获取的简单注册信息预先填充好。你可以继续要求额外的一些注册信息并且保持你网站当前对信息的要求,比如哪些必填,哪些可选填。(使用OpenID将加快注册速度,但并不是要求你你改变对注册信息的要求直至影响网站的正常行为)最后,你应该提供给已经注册用户绑定OpenId的链接。
  • 当用户完成注册流程,创建了一个新用户帐号,将可以使用AttachOpenID函数来绑定OpenID到新帐号上了。如果你的用户表和OpenID表分布在不同的数据库,不能同步进行访问,可能会导致绑定命令失败,从而导致鼓励帐号存在。这种情况不可能完美地组织,但也是非常罕见地,况且,用户可以重新登陆,你大可以忽视这种情况。
如果你已被验证的OpenID绑定到了一个已经存在的帐号上,通过传统的方法你也可以正常地登陆网站。如果用户正好用别的帐号登陆,注销掉,以OpenID绑定的帐号登陆。(未完待续)
内容有问题?请与我们联络。

译作评分

  • Currently 0.00/5
  • 1
  • 2
  • 3
  • 4
  • 5
 0.0  |  0 个评分

0条评论    0眉批

添加评论

欢迎访问译言网。在这里,您可以。。。

阅读
发现
翻译