CakePHP and OpenID

Published on January 11, 2007 and tagged with cakephp  component  openid  tutorial

This article is outdated, there is a newer tutorial!

You probably heard about OpenID, the open, decentralized, free framework for user-centric digital identity. It allows you to authenticate with just your URI and a password for all services which support OpenID.

The integration of OpenID into your (CakePHP) application is rather simple, and I wrote an OpenID component to make it even easier. Here the installation steps:

  • Download the PHP OpenID library (thanks to poLK for pointing me to this library) (the necessary files are now bundled with the component)
  • Get the OpenID component and place it in app/controllers/components
  • Put the folders “Auth” and “Services” from the zip to one of your vendors folders
  • If you don’t have the GMP or BCmath extension installed resp. enabled you have to add define(‘Auth_OpenID_NO_MATH_SUPPORT’, true); to Auth/OpenID/Consumer.php

Ok, when this is done, we can start with coding.

As usual when using a component we have to add it to the components array in our controller:

var $components = array('Openid');

Now we can implement our login action. It will perform three tasks: 1) Showing the login form where the user has to provide his/her OpenID URI, 2) Processing the login form and starting the authentication process, and 3) Processing the response of the OpenID server (see “OpenID protocol” for a high-level description of the protocol). So the skeleton of our login action looks like:

function login() {
    if (!empty($this->data)) {
       // handle form submission
    } else {
        if (count($_GET) > 1) {
            // process response from OpenID server
        }
    }
}

Step 1 is obvious, so I will move directly to step 2: Processing the login form and starting the authentication process. The authenticate function expects three parameters: the OpenID URI, the URL to which the OpenID server will redirect after the authentication process, and a trust root. I am not sure what this “trust root” is, up to now I didn’t found a good explanation. If you know one, please let me know…

if ($this->User->create($this->data) && $this->User->validates()) {
    $this->Openid->authenticate($this->data['User']['openid'], 'http://'.$_SERVER['SERVER_NAME'].'/users/login', 'http://'.$_SERVER['SERVER_NAME']);
}

The last step is to verify whether the authentication process was successful. If that is the case you usually set some session variables and redirect to a secured page.

$response = $this->Openid->getResponse();

if ($response->status == Auth_OpenID_SUCCESS) {
    // successfully authenticated
}

Ok, that’s it. Here the entire action:

function login() {
    if (!empty($this->data)) {
        if ($this->User->create($this->data) && $this->User->validates()) {
            $this->Openid->authenticate($this->data['User']['openid'], 'http://'.$_SERVER['SERVER_NAME'].'/users/login', 'http://'.$_SERVER['SERVER_NAME']);
        }
    } else {
        if (count($_GET) > 1) {
            $response = $this->Openid->getResponse();

            if ($response->status == Auth_OpenID_SUCCESS) {
                // successfully authenticated
            }
        }
    }
}

To test this action you need a valid OpenID, which you can get for example at MyOpenID.

Personally, I am switching to OpenID as it looks pretty cool and I can get rid of quite some code.

Anyway, have fun with OpenID :)

Update 2007-03-02: Installation instructions modified as now the necessary vendor files are bundled with the component.

62 comments baked

  • Tijs January 11, 2007 at 20:07

    great stuff, i was meaning to implement something similar but, as usual, you beat me to the punch. ;)

    I wonder how hard it would be to set it up with a shared secret so you don’t need to redirect to the openid server…

  • Christian Tietze January 11, 2007 at 22:14

    GREAT!

    I was always looking forward to implement OpenID in my applications but never really managed to have the authentication running properly. The documentation today, I have to admit, is really a lot better than a year ago.
    Zooomr.com uses OpenID and I really love this service :)

  • Dieter@be January 11, 2007 at 22:24

    Lol this is great.. about a week or so i started really reading more about openID and i thought “i should make a component for cakephp” but then i thought “naah somebody else will do it, probably dhofstet or so”

    i’m not joking! :)

  • programame.net January 11, 2007 at 22:33

    Integrando cakePHP y openID…

    La plataforma OpenID está ganando poderosos aliados últimamente por lo que es muy posible que dentro de unos pocos meses se convierta en una tecnología imprescindible. Para ir preparando el terreno, aquí podes ve como ntegrar facilmente una pasare…

  • Leandro Ardissone January 12, 2007 at 03:05

    Awesome, I was thinking on use OpenID in my apps.
    Thanks!

  • CakePHP y OpenID | Dr-Leech’s Blog January 12, 2007 at 03:21

    [...] Link: cakebaker – CakePHP and OpenID [...]

  • Tarique Sani January 12, 2007 at 07:24

    Cool and thanks

    I was also looking into this for adding to cheesecake for commenting (viewers will login using OpenID to comment) but the consumer library you point to, at 1.1mb, is bigger than cheesecake itself :P and probably bigger than many cake apps out there – so it is not a good fit for Open Soruce / Freely distributed apps

    Currently writing a simple single class consumer. Lets see how it turns out…

  • Mladen Mihajlovic January 12, 2007 at 08:35

    This is a nice explanation of trust roots: https://www.myopenid.com/help#tr

  • cakebaker January 12, 2007 at 18:06

    @all: Thanks for your comments.

    @Tijs: Hm, I think the redirection to an OpenID server is an essential part of the OpenID protocol.

    @Dieter@be: Oh, you are sooooo lazy ;-)

    @Tarique: Well, you don’t need all files in the package. The two folders “Auth” and “Services” only need ca. 300kB, and you probably can strip away some files not needed for a consumer.

    @Mladen: Thanks for the link.

  • kabturek January 12, 2007 at 22:51

    Great to see that people are starting to use OpenID :)

    @dho
    maybe it’s time to allow comments on this blog using OpenID ? :)
    Here are 2 WP plugins :
    http://verselogic.net/projects/wordpress/wordpress-openid-plugin/
    and
    http://the-notebook.org/12/01/2006/openid-comments-for-wordpress/

    there are some differences between them ;) i have a little comparison but in polish only.

  • cakebaker January 15, 2007 at 09:50

    @kabturek: Hm, what would be the advantage of using OpenID for comments?

  • kabturek January 15, 2007 at 15:12

    We wouldn’t have to write the usual name/email/www from different computers all the time ;) + the captcha would not be needed ( at least for now)
    now the ideological one ( the most important ! ; ) ) :
    you will spread OpenID ! :)

  • Tijs January 16, 2007 at 00:06

    @cakebaker: i guess your right, after reading this
    http://www.intertwingly.net/blog/2006/12/28/Unobtrusive-OpenID

    i was under the impression simple authentication could be done without logging in at your openid provider. it’s more of a captcha than anything else though i guess since you would still need to create an account at the website your trying to log in to.

  • cakebaker January 16, 2007 at 09:14

    @kabturek: I will test it.

    @Tijs: Yes, it is possible that you still have to create an account at the website. But there exists also the Simple Registration Extension (http://www.openidenabled.com/openid/simple-registration-extension) so that the website can get the registration data directly from OpenID.

  • cakebaker January 18, 2007 at 12:07

    @kabturek: I tested the first plugin (the second doesn’t look very promising) on my local machine with Wordpress 2.0.7, but I had some strange effects: I couldn’t no longer login to the admin area and the comments (including the comment form) were no longer shown. And the status information of the plugin didn’t show any failures (only that the GMP extension is not installed). So at least for the moment I don’t enable OpenID for comments.

  • kabturek January 23, 2007 at 13:27

    hmm it weird that you have such problems – i’ve seen couple of blogs that have them implemented without problems …

    these are polish blogs but they all allow openID comments and most of them are on WP:
    http://wiki.identity20.pl/index.php?title=Polskie_blogi_korzystaj%C4%85ce_z_OpenID

  • Montoya January 24, 2007 at 06:11

    Hi, I’m working on an app where I would like to use OpenID as the only form of user authentication. What fields would I use in my users database if the only login method is OpenID? Also, how would new users be created?

  • cakebaker January 24, 2007 at 11:44

    @kabturek: Yeah, it is strange. I tried it again with a fresh wordpress installation, but I had the same effect. So it is probably an issue with my configuration.

    @Montoya: It depends on your application. In my application I just store the OpenID url. And I create the user automatically when the authentication was successful.

  • kabturek January 24, 2007 at 13:02

    @Montoya: you must understand that OpenID isn’t a profile – its not meant to replace a user account.
    More info:
    http://simonwillison.net/2007/Jan/10/account/

  • Montoya January 24, 2007 at 18:36

    @kabturek: yes, I figured that out today when I was reading some openID documentation. Thanks.

    @cakebaker: OK, I have an idea now of what my users model needs to be and I have the controller already, I guess what I’m still having trouble with is building the views. I don’t know what the account creation step should look like… it’s pretty confusing and afaik no one in the cake community has built a site with openID user authentication so I don’t really know where to look. I guess I have more studying to do!

  • cakebaker January 24, 2007 at 19:58

    @Montoya: Well, it is not difficult, after the user is authenticated you show the registration form. Or you could use the Simple Registration Extension (http://www.openidenabled.com/openid/simple-registration-extension).

  • Montoya January 25, 2007 at 07:11

    From the comments there: “It is important to note that Simple Registration exists only for the convenience of the OpenID user. Consumer sites should be robust to OpenID servers that do not support simple registration, and should be able to ask the user for necessary infomation (if they really need it), and it is not available or provided during the OpenID transaction.”

    So, that doesn’t really make things simpler for me, just more convenient for the users. I think what I need to do is build a full user system with standard user accounts, since this is something I haven’t really done before, and then I can think about coming back and integrating openID into the system. After all, openID doesn’t guarantee trust, so I still have to do all the usual e-mail activation stuff anyway.

    Just out of curiosity, are there any tutorials on cookie-based user authentication in cakePHP? All I have seen are session-based methods.

  • navilon February 21, 2007 at 07:05

    Am i the only one who is getting errors?
    I’m developing on a windows machine with XAMPP. I follow the instructions given and this is what the action returns:
    http://localhost/users/login

    Warning: require_once(cake\libs\error.php) [function.require-once]: failed to open stream: No such file or directory in Z:\xampplite2\htdocs\cake\basics.php on line 461

    Fatal error: require_once() [function.require]: Failed opening required ‘cake\libs\error.php’ (include_path=’Z:\xampplite2\htdocs\app\\vendors\:Z:\xampplite2\htdocs\vendors\:Z:\xampplite2\htdocs;Z:\xampplite2\htdocs\app\;.;Z:\xampplite2\php\pear\’) in Z:\xampplite2\htdocs\cake\basics.php on line 461

    Line 19 in openid.php seems to be causing the problem

    ini_set(‘include_path’, $path);

    but i have no idea how to solve the issue.
    can anybody help?

  • Digital Spaghetti February 21, 2007 at 13:54

    Thanks very much, I’m just starting out with CakePHP, but one thing I wanted in my project from the start was OpenID support.

    I do think though, you can’t rely fully on it. I’m still building in a “back end” login system for at least 1 admin user, incase there are any issues the site owner can still log in.

  • m3nt0r February 22, 2007 at 01:22

    Hi. I was thinking about adding OpenID as feature to my current project, which already has an authentication.

    I have to questions here: Can i add additional infos to the auth, or am i bound to the data which the OpenID-account of the user provides?

    Furthermore: What happens if OpenID happends to be down, in case i would choose OpenID as my primary auth provider? No more login to my app?

    I am concerned about the reliability of this decentralized mechanism. Does your component offer any fallbacks?

  • cakebaker February 23, 2007 at 17:52

    @navilon: This issue has been fixed. You find the updated version in the downloads section.

    @Digital Spaghetti: Yes, that’s a possible way. Another way is to define a second OpenID using a different OpenID provider.

    @m3nt0r: Hm, I don’t know what you mean with your first question.

    Well, as OpenID is decentralized, it cannot be down. But of course it is possible that a single OpenID provider is down, but that affects only the users using that OpenID provider, and not all users of your app.

    No, the component does not offer any fallbacks.

  • sennet March 02, 2007 at 06:51

    It’s is very useful component.As i am have some problem. No XML parser was found how to solve this.give an expiation about the basic component used in this component.

  • Digital Spaghetti March 02, 2007 at 17:37

    Hey Daniel, great component now that it’s been fixed – works like a charm. I’ve posted a login function here (http://bin.cakephp.org/view/453008404) that anyone is free to use. The function basically takes a OpenID and verifies it. If the user is new, it creates a record in the local database. But if the user already exists, it logs them in.

  • cakebaker March 02, 2007 at 19:55

    @sennet: That issue is fixed in the latest package from today (2007-03-02).

    @Digital Spaghetti: Thanks for the example code.

  • m3nt0r March 09, 2007 at 19:34

    There is one problem with the example from digitalspaghetti. Not all services provide the infos you rely on. A possible way around this is: if the user has authed succesfully, but the SimpleReg is empty, set his account to inactive and direct him to a page where he appears logged in, but has to fill out the missing data first to move on.

    Like with MyOpenID, even it supports SimpleRegistration a user can still decide not to give you certain infos. Since we want to keep things simple, we tell him what we have and what’s missing, wait for input and then let him in.

    Hope this helps. Its really unfortunate that SimpleReg is not a default among the providers.

  • cakebaker March 10, 2007 at 10:57

    @m3nt0r: Yes, you cannot assume you get the data via SimpleRegistration, and it’s bad that SimpleRegistration is not a required feature for an OpenID server. I think your approach is a good way to deal with this situation.

  • Web App: Juvely » OpenID stuff (and some updates) March 24, 2007 at 21:15

    [...] I made my demo using good ol’ CakePHP and followed this guide which provides a component to allow you to easily integrate OpenID into your app. My demo works [...]

  • m3nt0r April 24, 2007 at 13:05

    i am suffering badly here…

    I keep getting: “No session state found”

    When i submit to /login/ the Yadis session info is placed into the session (tested ‘cake’ and ‘database’ storage) and the nonce key file is created in tmp.

    After allowing my trustroot, the service sends me back and the session info is removed, the nonce file is deleted and all i get is the error message. :(

    I tried myopenid, videntity and claimid

    My session is persistent though. I have a FQDN setup locally and the URLs are all correct.

    I am lost… please help.

    Possible related to cakes session renewal after redirect. But i have no idea how i could debug/stop or control any of this.

  • cakebaker April 24, 2007 at 18:05

    @m3nt0r: I got the same error message with Konqueror (it worked fine in FF). I had to set the constant CAKE_SECURITY in app/config/core.php from “high” to “medium”, that “solved” the problem.

    HTH

  • Jeremy Visser » links for 2007-06-08 June 08, 2007 at 02:45

    [...] cakebaker » CakePHP and OpenID (tags: cakephp openid php) This entry was written by Jeremy and posted on June 8, 2007 at 10:39 am and filed under Links. Bookmark the permalink. Follow any comments here with the RSS feed for this post. Post a comment or leave a trackback: Trackback URL. « CakePHP [...]

  • sarahk June 09, 2007 at 15:03

    Hi

    downloaded today and struck the “No XML parser was found in home/mysite/app/vendors/Services/Yadis/XML.php on line 359″ error. How do I fix this?

    thanks

    Sarah

  • sarahk June 09, 2007 at 15:13

    Oh, should have added… I get this on one server but another I’ve tested on is fine. It’s shared hosting so I does that mean I don’t have the xml capability so I can’t use OpenId?

  • cakebaker June 11, 2007 at 18:44

    @Sarah: Yes, it seems that XML support is required to use OpenID as in the code it looks for the DOM XML resp. DOM extensions.

  • Twittermon: Twitter for server-monitoring » nonsmokingarea.com » Blog Archive July 15, 2007 at 12:12

    [...] Twittermon was a matter of few hours, thanks to CakePHP and Daniel Hofstetter’s OpenID-component. if nothing else, at least I’ve learned how to authenticate via OpenID (dead [...]

  • Biffer Rowley July 21, 2007 at 20:29

    Hi – i want to port this to AS3 (Flash) and was wondering if you would help me out with the small adventure? I want to also port to AMFPHP so we can authenticate Flash Media Server users via an openID. I love the concept of openID & wnt to make it available to our beloved Flash community. And no , flash isnt just for animations these days :)

    Cheers,

    biffer

  • walkerhamilton July 23, 2007 at 15:27

    I’m having a problems with the “session”. When the openid auth gets back to my site, the session is nowhere to be found so the openid auth fails.

    Anybody have any clues?

  • walkerhamilton July 23, 2007 at 16:47

    Ah…..sorry, I found the comments above from m3ntor and cakebaker, to solve the problem.

  • cakebaker July 24, 2007 at 11:19

    @Biffer: It depends on where you need help ;-) (I never programmed with Flash)

    @Walker: Cool to hear you could solve the problem in the meantime :)

  • » » «Делаем стартап гостеприимным» или «Как использовать OpenID на своем сайте» [ NOVIKOV.UA ] создание сайта,раскрутка сайта,разработка сайт August 28, 2007 at 00:03

    [...] CakePHP или Symfony, вам достаточно настроить плагины CakePHP OpenID component и sfOpenIDPlugin соответсвенно. Если вы не используете [...]

  • Free PS3 September 10, 2007 at 12:23

    Thanks for the nice tutorial! i was searching for it for some time….keep it up man

  • Johny September 24, 2007 at 08:41

    Thak you very much ! You save my TIME :)

  • Johny September 24, 2007 at 09:57

    Hi in my opinion trust root is the “site address”. The provider (openID server) bind options with our visiting-card. On openID.pl i have problems with “bind” until I set trust url: on ‘http://’.$_SERVER['SERVER_NAME'].’/’
    Before openID.pl ask visiting-card every time.

  • cakebaker September 25, 2007 at 19:03

    @Johny: Thanks for your comments!

    What do you mean with “visiting-card”?

  • David January 05, 2008 at 14:36

    Thanks Daniel for the great extension and tutorial. But I’ve one question – what’s the difference when I’ve the Math support disabled? … define(’Auth_OpenID_NO_MATH_SUPPORT’, true);

  • cakebaker January 08, 2008 at 18:40

    @David: It means that there is no support for big integers. But according to the docs this is only relevant if you use the OpenID library for implementing an OpenID server: “If your site is low-security, define Auth_OpenID_NO_MATH_SUPPORT. The library will function, but the security of your OpenID server will depend on the security of the network links involved. If you are only using consumer support, you should still be able to operate securely when the users are communicating with a well-implemented server.”

    HTH

  • Toby February 12, 2008 at 02:52

    @cakebaker… The trust root looks like it is displayed to the user when the sign in with their OpenID provider, & is used to allow them to specify whether any subsequent requests from that “trust root” should be automatically authorised. If you are running your site under a subfolder of the root I would imaging that you would use the subfolder as the “trust root” so that the site root didn’t have access to the OpenID authorisation, but I could be wrong.
    T

  • cakebaker February 12, 2008 at 18:14

    @Toby: Yes, the “trust root” is usually the root of your application, so if you put your application into a sub folder, then the “trust root” is the sub folder.

  • nzfusion.com » Blog Archive » WP-OpenID - WordPress Plugins February 20, 2008 at 03:45

    [...] Those are two reasons… if you have a blog then there is a WordPress OpenID Plugin, if you don’t then perhaps there is a plugin for the platform/framework you are using… Is there one for CakePHP? Yes it turns out that there is an OpenID component for CakePHP. [...]

  • knud March 08, 2008 at 22:53

    The is no “Auth” and “Services” in the zip file.
    unzip -l openid_component_2008-02-06.zip
    Archive: openid_component_2008-02-06.zip
    Length Date Time Name
    ——– —- —- —-
    0 01-11-07 09:07 app/
    0 01-11-07 09:07 app/controllers/
    0 01-11-07 09:07 app/controllers/components/
    2896 02-06-08 08:35 app/controllers/components/openid.php
    ——– ——-
    2896 4 files

  • cakebaker March 09, 2008 at 18:44

    @knud: The OpenID library is no longer bundled with the current version of the OpenID component, you have to download it separately. Please have a look at the installation instructions on the download page.

  • David Collantes April 29, 2008 at 01:58

    I wish WP would incorporate CakePHP, to handle OpenID cleanly. It is a sad state of affair the way it is right now (no official OpenID and plugins work badly).

  • Kevin May 26, 2008 at 16:00

    I don’t understand how to protect a page from beeing see by unregistered users. Where can I find more information about that.

  • cakebaker May 26, 2008 at 17:23

    @Kevin: You can find a simple example in the manual: Simple user authentication.

    I hope it helps!

  • http://asadmehmoodstar.myopenid.com/ September 18, 2008 at 12:29

    i have a problem here. i followed the same steps u mentioned above. but at the end it returns me an error that getResponse() function requaires 1 argument.

    Then i gone to the location where this function is defined i saw i accept an argument called current url. can u tell me that what is this.

  • cakebaker September 18, 2008 at 17:36

    @asad: Please have a look at the newer tutorial you can find here: http://cakebaker.42dh.com/2008/02/06/new-version-of-the-openid-component/. The instructions in this article are outdated, I’m sorry for the inconvenience…

  • infrascape February 13, 2009 at 09:54

    This is really usefil in PHP, i have solved my issues.

  • cakebaker February 14, 2009 at 17:28

    @infrascape: Good to hear ;-)

Bake a comment




(for code please use <code>...</code> [no escaping necessary])

© daniel hofstetter. Licensed under a Creative Commons License