Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1285957
  • 博文数量: 315
  • 博客积分: 10397
  • 博客等级: 上将
  • 技术积分: 3731
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-07 21:21
文章分类

全部博文(315)

文章存档

2015年(10)

2014年(3)

2013年(2)

2012年(8)

2011年(8)

2010年(29)

2009年(59)

2008年(77)

2007年(119)

分类:

2008-03-03 10:30:24

简单注册插件

为了认证,OPENID可以使用轻量级的资料交换。该特性并不是由OpenId认证所描述,而是由OPENID简单注册插件协议所规范。该协议允许启用OPENID站点查询一个从OPENID Provider传回的终端用户的信息。

这样的信息可能包含:

1、 别名――任何终端用户想使用的一串UTF-8的字符串作为别名

2、 邮件――由RFC28223.4.1章节所规范的终端用户邮件地址

3、 全名――一串表示终端用户全名的UTF-8字符串

4、 出生日期(DATE OF BIRTHDOB)――以YYYY-MM-DD为格式的终端用户出生日期。如果标识该日期的值少于指定数字则用0来填充。这些值的长度总为十进位。如果没有指定则设为0。比如只设定年份1980,则该值为“1980-00-00

5、 Gender――性别

6、 Postcode――邮编

7、 Country――国家

8、 Language――语言

9、 Timezone――时区

一个启用OPENID的网络站点可能会要求这些字段的综合。它也可能严格的需要一些信息,并且允许用户提供和隐藏其他的信息。下面一个例子就是创建一个Zend_OpenId_Extension_Sreg类的对象需要一个别名,以及可选的email和全名。

 

require_once "Zend/OpenId/Consumer.php";
require_once 
"Zend/OpenId/Extension/Sreg.php"
;

$sreg = new Zend_OpenId_Extension_Sreg
(array(
    
'nickname'=>true
,
    
'email'=>false
,
    
'fullname'=>false), null1.1
);
$consumer = new Zend_OpenId_Consumer
();
if (!
$consumer->login($_POST['openid_identifier'], 'example-6_3.php'null$sreg
)) {
    die(
"OpenID login failed."
);
}

 

正如你所看到的Zend_OpenId_Extension_Sreg构造器接收一个所需字段的数组。该数组以字段名为其索引,所需标签为其值。True标识该字段是必须的,false则标示该字段是可选的。Zend_OpenId_Consumer::login接受该插件或是插件列表为其第四个参数。

作为认证的第三步,Zend_OpenId_Extension_Sreg对象应该传值给Zend_OpenId_Consumer::verify。成功认证后Zend_OpenId_Extension_Sreg::getProperties将返回一个请求字段的关联数组。

 

require_once "Zend/OpenId/Consumer.php";
require_once 
"Zend/OpenId/Extension/Sreg.php"
;

$sreg = new Zend_OpenId_Extension_Sreg
(array(
    
'nickname'=>true
,
    
'email'=>false
,
    
'fullname'=>false), null1.1
);
$consumer = new Zend_OpenId_Consumer
();
if (
$consumer->verify($_GET$id$sreg
)) {
    echo 
"VALID $id
\n"
;
    
$data $sreg->getProperties
();
    if (isset(
$data['nickname'
])) {
        echo 
"nickname: " $data['nickname'] . "
\n"
;
    }
    if (isset(
$data['email'
])) {
        echo 
"email: " $data['email'] . "
\n"
;
    }
    if (isset(
$data['fullname'
])) {
        echo 
"fullname: " $data['fullname'] . "
\n"
;
    }
} else {
    echo 
"INVALID $id"
;
}

如果Zend_OpenId_Extension_Sreg创建时没有带任何参数,用户代码会校验所需数据是否存在。然而,如果它创建时带了同样的所需字段列表,它也将会自动校验所需数据是否存在。在上例中,如果丢失了任何所需的字段,Zend_OpenId_Consumer::verify将返回false

缺省情况下,Zend_OpenId_Extension_Sreg使用http1.0,因为1.1尚未定案。但有些服务器所请求的SREG名称空间里只支持1.1。这样你就必须在中Zend_OpenId_Extension_Sreg特定的设定为1.1的版本。

第二个Zend_OpenId_Extension_Sreg构造器的参数是一个规范URL,一般由标识Provider所提供。

 

Zend_Auth集成

Zend Framework提供了一个特别的类用来做用户认证――Zend_Auth。该类可以与Zend_OpenId_Consumer一起使用。下面的例子显示了OpenIdAdapter怎样实现Zend_Auth_Adapter_Interface的认证方法。它发起了一个认证的查询和校验。

这个adapter与已经存在的Adapter最大的不同就是,它针对两个HTTP的请求,并且包含了一个指派码来进行第二步和第三步的OPENID认证。

 

require_once "Zend/OpenId/Consumer.php";
require_once 
"Zend/Auth.php"
;
require_once 
"Zend/Auth/Adapter/Interface.php"
;

class 
OpenIdAdapter implements Zend_Auth_Adapter_Interface 
{
    private 
$_id null
;

    public function 
__construct($id null
) {
        
$this->_id $id
;
    }

    public function 
authenticate
() {
        
$id $this->_id
;
        if (!empty(
$id
)) {
            
$consumer = new Zend_OpenId_Consumer
();
            if (!
$consumer->login($id
)) {
                
$ret false
;
                
$mdg "Authentication failed."
;
            }
        } else {
            
$consumer = new Zend_OpenId_Consumer
();
            if (
$consumer->verify($_GET$id
)) {
                
$ret true
;
                
$msg "Authentication successful"
;
            } else {
                
$ret false
;
                
$msg "Authentication failed"
;
            }
        }
        return new 
Zend_Auth_Result($ret$id, array($msg
));
    }
}

$status ""
;
$auth Zend_Auth::getInstance
();
if ((isset(
$_POST['openid_action'
]) &&
     
$_POST['openid_action'] == "login" 
&&
     !empty(
$_POST['openid_identifier'
])) ||
    isset(
$_GET['openid_mode'
])) {
    
$adapter = new OpenIdAdapter(@$_POST['openid_identifier'
]);
    
$result $auth->authenticate($adapter
);
    if (
$result->isValid
()) {
        
Zend_OpenId::redirect(Zend_OpenId::selfURL
());
    } else {
        
$auth->clearIdentity
();
        foreach (
$result->getMessages() as $message
) {
            
$status .= "$message
\n"
;
        }
    }
} else if (
$auth->hasIdentity
()) {
    if (isset(
$_POST['openid_action'
]) &&
        
$_POST['openid_action'] == "logout"
) {
        
$auth->clearIdentity
();
    } else {
        
$status "Yoy are logged-in as " $auth->getIdentity() . "
\n"
;
    }
}
?>

echo "$status";
?>


OpenID Login



 

使用Zend_Auth将终端用户的标识保存进了session的数据。它可以由Zend_Auth::hasIdentityZend_Auth::getIdentity进行查询。

 

Zend_Controller进行集成

最后的一些话是关于与M-V-C应用程序的集成。比如ZF应用程序是使用Zend_Controller类来实现,他们使用Zend_Controller_Response_Http类的对象来准备HTTP的响应并且发送它们到终端用户的浏览器。

Zend_OpenId_Consumer并没有提供任何GUI的能力但它在Zend_OpenId_Consumer::loginZend_OpenId_Consumer::check成功后会发起HTTP的重定向。这些重定向如果已经被传送给了浏览器,也许不会正确的工作甚至根本不工作。为了正确的发起以MVC代码方式的重定向,真实的Zend_Controller_Response_Http应该被传送给Zend_OpenId_Consumer::login或者Zend_OpenId_Consumer::check作为最后一个参数。

阅读(878) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~