Updates from January, 2008 Toggle Comment Threads | Keyboard Shortcuts

  • steve918 4:35 pm on January 28, 2008 Permalink | Reply  

    Using JanRain OpenID with Zend Framework 

    Ok, I know Zend_OpenId is on the way, but for those of us who don’t like to wait here’s a way to get OpenID working with Zend Framework. Besides, JanRain’s libraries tend to be pretty solid and up to date so you won’t go wrong using this in place of Zend_OpenId if you choose to in the future.

    This implementation is pretty simple. They only thing thrown in is support for saving the last page the user visited on your site so you can return them there once authentication is finished.

    I didn’t include any extension support for the simplicity sake, but if you wanted to add Simple Registration or something the examples that come with the JanRain libraries are fairly straightforward.

    session = Zend_Registry::getInstance()->get('session');
            $this->store = $this->getFileStore();
            $this->consumer = new Auth_OpenID_Consumer($this->store);
        }
    
        /**
         * Create a file store object for consumer
         */
        public function getFileStore() {
            $store_path = "/tmp/openid";
    
            if(!file_exists($store_path) && !mkdir($store_path) ) {
                echo "Could not create file store.";
                exit;
            }
    
            return new Auth_OpenId_FileStore($store_path);
        }
    
        /**
         * This is the default action for the controller. Which
         * does two basic things.
         * 1. Records what page the user came from so we can return
         *    them there after login.
         * 2. Renders the index view. (Login form).  Since this is the
         *    index action it will automatically render
         *    views/scripts/login/index.phtml without explicitly calling
         *    $this->view->render('index');
         */
        public function indexAction() {
    
            // Save the page the user was last at and return them to it
            // after authentication.
            $return_url = parse_url($_SERVER['HTTP_REFERER']);
            if($return_url['host'] == $this->domain) {
                    $return = $return_url['path'];
                    if(strlen($return_url['query'])) {
                        $return .= "?" . $return_url['query'];
                    }
                    if(strlen($return_url['fragment'])>0) {
                        $return .= "#" . $return_url['fragment'];
                    }
                    $this->session->loginReturn = $return;
            }
        }
    
       /**
        * The login view from the index action posts to this action, then
        * we call consumer->begin() whichs starts the openid login process
        * with the open id from the form post.
        */
        public function tryAction() {
            try {
                // Make sure the user entered something.
                if(strlen($this->openid) == 0) {
                    throw new Exception('OpenID is empty.');
                }
    
                // Try to start an openid authentication.
                $auth_request = $this->consumer->begin($this->openid);
    
                if(!$auth_request) {
                    throw new Exception("No Auth Request");
                }
    
               $redirect_url = $auth_request
                  ->RedirectURL($this->getTrustRoot(),$this->getReturnTo());
    
                if (Auth_OpenID::isFailure($redirect_url)) {
                    throw new Exception("Could not redirect to server: "
                      . $redirect_url->message);
                }
    
            } catch (Exception $e) {
                $this->view->error = $e->getMessage();
                $this->render('index');
                return;
            }
    
            header("Location: ".$redirect_url);
            $this->render('index');
        }
    
        /**
         * When the identity provider is done having their
         * moment with the user they get returned to this action.
         * Here we look at the response status codes to decide
         * to if they were authenticated or not.
         */
        public function finishAction() {
                $return_to = $this->getReturnTo();
                $response = $this->consumer->complete($return_to);
    
                if($response->status == Auth_OpenID_CANCEL) {
                    $this->view->error = 'Verification cancelled.';
                } else if ($response->status == Auth_OpenID_FAILURE) {
                    $this->view->error = "OpenID authentication failed: "
                      . $response->message;
                } else if ($response->status == Auth_OpenID_SUCCESS) {
                    $this->view->error =  "Success";
                    if(isset($this->session->loginReturn) &&
                       strlen($this->session->loginReturn) > 0) {
                        $user = new User($response->identity_url);
                        if($user->isEnrolled()) {
    
                            // TODO:  Vodoo for setup up a user session and
                            // logging them in.
    
                            // If the user is enrolled, return them to the page
                            // they visited before the
                            header("Location: " . $this->session->loginReturn);
                            exit;
                        }
                        // The user was logged in successfully, but this is
                        // their first time on your site, so send them through
                        // enrollment.
                        header("Location: /enroll");
                    }
                }
            $this->render('index');
        }
    
        //////////////////////////////////////
        //  HELPER FUNCTIONS
        /////////////////////////////////////
    
        /**
         * Returns http or https depending on the current protocol
         */
        private function getScheme() {
            $scheme = 'http';
            if (isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] == 'on') {
                $scheme .= 's';
            }
            return $scheme;
        }
    
        /**
         * Answers the URL we wish for the identity provider to return
         * a user to once the authentication process is finished.
         */
        private function getReturnTo() {
            return sprintf("%s://%s/login/finish",
                           $this->getScheme(), $_SERVER['SERVER_NAME']);
        }
    
        /**
         * Answers the trust root for this domain.
         */
        private function getTrustRoot() {
            return sprintf("%s://%s/", $this->getScheme(),
             $_SERVER['SERVER_NAME']);
        }
    }
    
    ?>
    
    
     
    • Riki Risnandar 11:56 am on July 6, 2009 Permalink | Reply

      thank you for sharing this OpenId article … great for starting in zend framework.

      i am using php 5 and in JanRain library there is lot’s of warnings and deprecated functions.

      • steven 8:51 pm on July 19, 2009 Permalink | Reply

        Hey, np. You should look the current Zend OpenID implementation. It was a little rough at the time I wrote this, but I understand it’s come a long way since then. It’s currently being used by my employer (SourceForge.net) although they integrated it before I joined the company.

        Re: warnings/deprecations I’m not certain, but I’m guessing it has to do with the JanRain libraries aiming for PHP4 compatibility.

  • steve918 4:00 pm on January 27, 2008 Permalink | Reply  

    What everyone's Zend_View_Helper tutorials leave out. 

    There seems to be several Zend_View_Helper tutorials out there and all of them talk about what a view helper is and does, but I always left with one question: How do I make the helpers available to ALL of my views?

    Then I learned a bit about Zend_Controller_Action_HelperBroker

    This class can work all kinds of magic, but the one thing we care about right now is that it will allow you to register a global View object to be passed to your Controller script. So all you have to do is create your own View and use addHelperPath() to tell it where your View helpers are and register your view with Controler_Action_HelperBroker

    Just add the following bit of code to your front controller:

    //Setup view helpers
    Zend_Loader::loadClass('Zend_View');
    $view = new Zend_View();
    $helper_path = "/var/www/myhelpers";
    $view->addHelperPath($helper_path,'View_Helper');
    Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer')
      ->setView($view);
    
     
c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
Reply
e
Edit
o
Show/Hide comments
t
Go to top
l
Go to login
h
Show/Hide help
shift + esc
Cancel