
A CakePHP component to make it easier to integrate OpenID into your applications. It requires PHP5 and CakePHP 1.2/1.3, and it depends on the (open source) PHP OpenID library by JanRain. Also make sure the curl and openssl extensions are enabled in your PHP installation, or else OpenIDs using https (e.g. Google's OpenID) will cause an "Invalid OpenID" error.
The component is licensed under the MIT license.
Please note that the PHP OpenID library doesn't yet work on PHP 5.3, though a modified version by Miguel Santirso seems to work.

(latest release: 2009-12-12, see also the changelog)
Or you can get it with: git clone git://github.com/cakebaker/openid-component.git
By default, the OpenID component stores all data in "app/tmp/openid". If you want to store those data in a (MySQL) database, follow these steps:
public $components = array('Openid' => array('use_database' => true)); (uses the "default" database configuration)public $components = array('Openid' => array('database_config' => 'name_of_database_config'));The OpenID component supports the Email Address to URL Translation (EAUT) protocol. To enable this feature, you have to perform the following two steps:
At first we need a login form:
<?php
// app/views/users/login.ctp
if (isset($message)) {
echo '<p class="error">'.$message.'</p>';
}
echo $form->create('User', array('type' => 'post', 'action' => 'login'));
echo $form->input('OpenidUrl.openid', array('label' => false));
echo $form->end('Login');
?>
And now we have to write a controller to handle this form. Our controller has to do the following: show the login form, redirect the user to the OpenID provider when the user submits the login form, and last, but not least, deal with the response from the OpenID provider.
// app/controllers/users_controller.php
class UsersController extends AppController {
public $components = array('Openid');
public $uses = array();
public function login() {
$returnTo = 'http://'.$_SERVER['SERVER_NAME'].'/users/login';
if (!empty($this->data)) {
try {
$this->Openid->authenticate($this->data['OpenidUrl']['openid'], $returnTo, 'http://'.$_SERVER['SERVER_NAME']);
} catch (InvalidArgumentException $e) {
$this->setMessage('Invalid OpenID');
} catch (Exception $e) {
$this->setMessage($e->getMessage());
}
} elseif ($this->Openid->isOpenIDResponse()) {
$response = $this->Openid->getResponse($returnTo);
if ($response->status == Auth_OpenID_CANCEL) {
$this->setMessage('Verification cancelled');
} elseif ($response->status == Auth_OpenID_FAILURE) {
$this->setMessage('OpenID verification failed: '.$response->message);
} elseif ($response->status == Auth_OpenID_SUCCESS) {
echo 'successfully authenticated!';
exit;
}
}
}
private function setMessage($message) {
$this->set('message', $message);
}
}
If you test this example with an OpenID from Yahoo! you will notice the following warning issued by Yahoo!: "Warning: Yahoo! cannot verify this website. We recommend you do not share any personal information with this website." To get rid of this warning, please see the article Enabling your application for return URL verification.
The Simple Registration Extension allows you to retrieve nine commonly requested pieces of information: nickname, email, fullname, dob (date of birth), gender, postcode, country, language, and timezone.
// app/controllers/users_controller.php
class UsersController extends AppController {
public $components = array('Openid', 'RequestHandler');
public function login() {
$realm = 'http://'.$_SERVER['SERVER_NAME'];
$returnTo = $realm . '/users/login';
if ($this->RequestHandler->isPost()) {
$this->makeOpenIDRequest($this->data['OpenidUrl']['openid'], $returnTo, $realm);
} elseif ($this->Openid->isOpenIDResponse() {
$this->handleOpenIDResponse($returnTo);
}
}
private function makeOpenIDRequest($openid, $returnTo, $realm) {
$required = array('email');
$optional = array('nickname');
$this->Openid->authenticate($openid, $returnTo, $realm, array('sreg_required' => $required, 'sreg_optional' => $optional));
}
private function handleOpenIDResponse($returnTo) {
$response = $this->Openid->getResponse($returnTo);
if ($response->status == Auth_OpenID_SUCCESS) {
$sregResponse = Auth_OpenID_SRegResponse::fromSuccessResponse($response);
$sregContents = $sregResponse->contents();
if ($sregContents) {
if (array_key_exists('email', $sregContents)) {
debug($sregContents['email']);
}
if (array_key_exists('nickname', $sregContents)) {
debug($sregContents['nickname']);
}
}
}
}
}
Attribute Exchange allows you to retrieve identity information from the OpenID provider, if supported. http://www.axschema.org/types contains a list with possible attribute names, though only a small subset is usually supported by the OpenID providers.
// app/controllers/users_controller.php
class UsersController extends AppController {
public $components = array('Openid', 'RequestHandler');
public function login() {
$realm = 'http://'.$_SERVER['SERVER_NAME'];
$returnTo = $realm . '/users/login';
if ($this->RequestHandler->isPost()) {
$this->makeOpenIDRequest($this->data['OpenidUrl']['openid'], $returnTo, $realm);
} elseif ($this->Openid->isOpenIDResponse() {
$this->handleOpenIDResponse($returnTo);
}
}
private function makeOpenIDRequest($openid, $returnTo, $realm) {
$attributes[] = Auth_OpenID_AX_AttrInfo::make('http://axschema.org/namePerson');
$this->Openid->authenticate($openid, $returnTo, $realm, array('ax' => $attributes));
}
private function handleOpenIDResponse($returnTo) {
$response = $this->Openid->getResponse($returnTo);
if ($response->status == Auth_OpenID_SUCCESS) {
$axResponse = Auth_OpenID_AX_FetchResponse::fromSuccessResponse($response);
if ($axResponse) {
debug($axResponse->get('http://axschema.org/namePerson'));
debug($axResponse->getSingle('http://axschema.org/namePerson'));
}
}
}
}
If you have questions, feedback, or you simply want to say "hi", contact me via Twitter (@dhofstet) or send me an email (daniel.hofstetter at 42dh.com). Have fun :)
To learn more about OpenID in general, have a look at the OpenID specification, check out the free "Get Ready for OpenID" book (this book is unfortunately no longer available, its site, openidbook.com, displays only a bunch of ads right now), or wait for the upcoming book OpenID: The Definitive Guide from O'Reilly.