<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>cakebaker &#187; authentication</title>
	<atom:link href="http://cakebaker.42dh.com/tags/authentication/feed/" rel="self" type="application/rss+xml" />
	<link>http://cakebaker.42dh.com</link>
	<description>baking cakes with CakePHP</description>
	<lastBuildDate>Tue, 20 Dec 2011 15:29:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>How to use the OpenID component with the Auth component</title>
		<link>http://cakebaker.42dh.com/2008/12/09/how-to-use-the-openid-component-with-the-auth-component/</link>
		<comments>http://cakebaker.42dh.com/2008/12/09/how-to-use-the-openid-component-with-the-auth-component/#comments</comments>
		<pubDate>Tue, 09 Dec 2008 16:02:39 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[authentication]]></category>
		<category><![CDATA[cakephp]]></category>
		<category><![CDATA[component]]></category>
		<category><![CDATA[openid]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=994</guid>
		<description><![CDATA[Please note that the hack described in this article no longer works with CakePHP 1.2.3.8166! See Peter&#8217;s comment for a possible solution for the current CakePHP release (1.2.5.x). Some days ago I got asked how you can use the OpenID component together with the Auth component from CakePHP. As I didn&#8217;t knew the answer, I [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Please note that the hack described in this article no longer works with CakePHP 1.2.3.8166! See <a href="http://cakebaker.42dh.com/2008/12/09/how-to-use-the-openid-component-with-the-auth-component/#comment-133898">Peter&#8217;s comment</a> for a possible solution for the current CakePHP release (1.2.5.x).</strong></p>
<p>Some days ago I got asked how you can use the <a href="http://cakebaker.42dh.com/downloads/openid-component-for-cakephp/">OpenID component</a> together with the Auth component from CakePHP.</p>
<p>As I didn&#8217;t knew the answer, I had to experiment a bit. Even though it was a quite frustrating experience (thanks to the strange design of the Auth component and too much automagic), I finally managed to find a &#8220;solution&#8221;. It is rather a hack, but it seems to work ;-)</p>
<p>Ok, here we go. </p>
<p>The first step is to create the login form. Because the Auth component expects the login credentials to consist of username and password, we have to add a (hidden) field for the password.</p>
<pre>
<code>&lt;?php
// app/views/users/login.ctp
$session-&gt;flash('auth');

echo $form-&gt;create('User', array('action' =&gt; 'login'));
echo $form-&gt;input('username', array('label' =&gt; 'OpenID:'));
echo $form-&gt;input('password', array('type' =&gt; 'hidden'));
echo $form-&gt;end('Login');
?&gt;</code>
</pre>
<p>The next step is to create the UsersController. The login() method is a bit special in this case, it is called three times: when you visit the login form, when you submit the login form, and when you come back from the OpenID provider. The rest of the code should be self-explanatory (if not, please leave a comment).</p>
<pre>
<code>// app/controllers/users_controller.php
class UsersController extends AppController {
    public $components = array('Auth', 'Openid', 'RequestHandler');
 
    public function beforeFilter() {
        $this-&gt;Auth-&gt;loginError = 'Login failed';
    }
    
    public function login() { 
        $returnTo = 'http://'.$_SERVER['SERVER_NAME'].'/users/login';
		
        if ($this-&gt;RequestHandler-&gt;isPost()) {   
    	    $this-&gt;makeOpenIDRequest($this-&gt;data['User']['username'], $returnTo);
        }
    	
        if ($this-&gt;isOpenIDResponse()) {
            $this-&gt;handleOpenIDResponse($returnTo);
        }
    }
    
    private function makeOpenIDRequest($openid, $returnTo) {
        try {
            $this-&gt;Openid-&gt;authenticate($openid, $returnTo, 'http://'.$_SERVER['SERVER_NAME']);
        } catch (Exception $e) {
            // empty
        }
    }
    
    private function isOpenIDResponse() {
        return (count($_GET) &gt; 1);
    }
    
    private function handleOpenIDResponse($returnTo) {
        $response = $this-&gt;Openid-&gt;getResponse($returnTo);
        $this-&gt;Auth-&gt;login($response);
        $this-&gt;redirect($this-&gt;Auth-&gt;redirect());
    }
    
    public function logout() {
        $this-&gt;redirect($this-&gt;Auth-&gt;logout());
    }
}</code>
</pre>
<p>As you can see in the handleOpenIDResponse() method, we pass the OpenID response object to the login method of the Auth component. As the Auth component cannot know how to deal with that object, we have to write some functionality to deal with the response object. For this purpose we have to override the find() method of the User model, as it is the method which is eventually called by the Auth component if you call its login() method. The response object is passed to the find() method in the $conditions array and is available via the strange &#8220;`User`.`id`&#8221; key. The implementation itself is quite simple: you have to return an array with user data if the login was successful, or an empty array if the login was not successful. </p>
<pre>
<code>// app/models/user.php
class User extends AppModel {
    public function find($conditions = null, $fields = array(), $order = null, $recursive = null) {	
        if (is_array($conditions) &amp;&amp; isset($conditions['`User`.`id`'])) {
            $response = $conditions['`User`.`id`'];
			
            if ($response-&gt;status == Auth_OpenID_SUCCESS) {
                return array('User' =&gt; array('openid' =&gt; $response-&gt;identity_url));
            }
			
            return array();
        }

        if (is_array($conditions) &amp;&amp; isset($conditions['User.username']) &amp;&amp; isset($conditions['User.password'])) {
            return array();
        }
		
        return parent::find($conditions, $fields, $order, $recursive);
    }
}</code>
</pre>
<p>Especially if you have only an OpenID column in your table you have to hinder the Auth component from performing a find() operation using the non-existing columns &#8220;username&#8221; and &#8220;password&#8221;, hence the check in the example whether those conditions are set.</p>
<p>With that, it should now be possible to login with your OpenID into your application protected by the Auth component.</p>
<p>I hope this is useful for some of you!</p>
<p>Update (2008-12-24): Fixing some small issues mentioned by <a href="http://lboy.wordpress.com/">lboy</a> in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/12/09/how-to-use-the-openid-component-with-the-auth-component/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
	</channel>
</rss>

