1.安装一个OpenID用户库
- 目前已经有很多流行编程语言的OpenID库,它们替你解决了绝大部分的负担。
- 在库的基础上,你需要建立和提供者网站之间的联系,实质上,就是建立把服务和处理器处理成连接字符串。你至少需要把这种联系存储在session中,用来验证一个OpenID的授权,但比较完美的情况还是你长期存储他们,这样就不用每次重定向到OpenID提供者时都重新建立他们之间的联系。你可以用 memcached、数据库或者其他你能访问到的存储介质。
- 你可以使用下面的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的最大好处是用户不用再维护他们在各个网站不同的注册信息。
- 添加OpenID用户登陆的内容到登陆页面。这对已经注册并绑定了OpenID的用户和用OpenID注册的新用户都是有用的。想注册页面一样,UI的设计目标是需要保持非OpenID用户和OpenID用户之间的平衡。你应该使OpenID输入框的命名和样式和注册页面保持一致。包围输入框的form也应该只想你将创建的动态页面。
- 在网站其他任何有传统登陆方式的地方,你都应该增加OpenID的登陆方式。
- 必须提供两个基本的访问参数给动态页面
- openid_url:用户指定的OpenID,包括注册、登陆、绑定等。
- action_type:用户要采用的操作类型。这个参数的只有可能是login、complete、attach、list和delete。(如果你用Rails或者类似的体系,这些可能是一个控制器方法或者url本身的一部分)
- 实现login动作(这是在注册和登陆流程里边都要提交到的地方)
- 用上文提到的GetUserId函数获取openid_url。
- 如果OpenID已经被你网站的用户绑定过了,检查这个用户是不是已经在你的网站登陆了。
- 如果这个用户还没有登陆,则用户是试图用这个帐号登陆,所以需要准备重定向到对应的OpenID提供者,但是需要设置一个标记表明不是用来注册。
- 如果用户已经登陆了,而且这个OpenID属于用户(也就是说,这个OpenID的URL已经关联到这个登陆用户的user_id),你就不需要做任何事情(这个用户已经登陆而且已经绑定了这个OpenID,所以这是相当于没操作),这是一个特殊情况。
- 如果这个用户已经登陆了,但OpenID属于另一个用户,则提示这个账户已经被另外的用户绑定过了。你同事可以提供注销和再试一次的选项。这是另一种特殊情况。
- 当OpenID提供者返回到你的return_to地址时,他们会在地址上添加一些用来验证用户授权信息的请求参数。通过你使用的OpenID库,你可能需要收集这些信息为指定的数据结构,用来通过验证函数,也有可能它自己就帮你做好这些事情了。
- 从session中获取用户最初请求的OpenID。
- 调用OpenID库中的id_res来验证你发给OpenID提供者的授权数据。传给用户请求的原始OpenID,以及一些必要的请求参数。这个函数将检查是不是一切都有效。如果它返回错误信息,给用户提示适当的一些信息;否则你就可以正式确认这个用户的合法性了。
- 在验证成功后,你也可以在你的网站给这个OpenID设置一个永久的cookie,下次这个用户进入网站的时候就可以在OpenID输入框预先填充好这个OpenID了。如果这样做的话,需要确保当用户注销时清除掉这个cookie。
- 用GetUserId函数重新获取验证过的OpenID。如果你不能从数据库中获取,检查用户是不是这会已经登陆了。如果是,执行attach动作绑定OpenID到用户已经存在的帐号。否则,是时候启动注册进程创建一个使用改OpenID的新帐户了。保存OpenID到session,这样账户创建的代码将能确保这个用户已经验证过这个OpenID了。(不要使用存取请求过的OpenID的session变量了,因为用户可以输入任何内容给那个变量)然后将用户重定向到注册流程,并填充你获取的简单注册信息(如果有的话),因此你需要想办法把返回的这些注册信息和你网站平常使用的注册信息关联起来。
- 像上面所描述的一样,注册页面应该非常显著地显示OpenID,并且不要在此要求用户为你的网站输入密码,因为他们已经使用OpenID登陆了。另外,你应该把从OpenID提供者获取的简单注册信息预先填充好。你可以继续要求额外的一些注册信息并且保持你网站当前对信息的要求,比如哪些必填,哪些可选填。(使用OpenID将加快注册速度,但并不是要求你你改变对注册信息的要求直至影响网站的正常行为)最后,你应该提供给已经注册用户绑定OpenId的链接。
- 当用户完成注册流程,创建了一个新用户帐号,将可以使用AttachOpenID函数来绑定OpenID到新帐号上了。如果你的用户表和OpenID表分布在不同的数据库,不能同步进行访问,可能会导致绑定命令失败,从而导致鼓励帐号存在。这种情况不可能完美地组织,但也是非常罕见地,况且,用户可以重新登陆,你大可以忽视这种情况。












如何让你的网站也支持OpenID(二)
翻译: 