Using OpenID with Zend Framework

2019-02-15 14:59发布

问题:

I want my website to do exactly what Stackoverflow does with openId.

I'm combing through sources, and I have done this before with facebook, but not making much progress with OpenID.

What I would like to do is just detect if someone has logged into Google, and if they have get some identifying information, and allow them to federate into my site.

Can anyone suggest any tutorials or Code snippets, and should I use Zends Libraries ?

-P

回答1:

/**
 * SM's code library
 * 
 * @category    
 * @package     
 * @subpackage  
 * @copyright   Copyright (c) 2009 Pavel V Egorov
 * @author      Pavel V Egorov <epavel@gmail.com>
 * @link        http://epavel.ru/
 * @since       29.04.2010
 */

/*
 * в configs/application.ini 
 * 
 * ;php-openid library
 * includePaths[] = APPLICATION_PATH "/../include/php-openid-2.1.3"
 * autoloadernamespaces[] = Auth_ 
 */


define ('Auth_Yadis_CURL_OVERRIDE', true);
define ('Auth_OpenID_RAND_SOURCE', null);

class Smapp_Auth_Adapter_OpenId implements Zend_Auth_Adapter_Interface
{
    /**
     * The identity value being authenticated
     *
     * @var string
     */
    protected $_id = null;

    /**
     * Reference to an implementation of a storage object
     *
     * @var Auth_OpenID_OpenIDStore
     */
    protected $_storage = null;

    /**
     * The URL to redirect response from server to
     *
     * @var string
     */
    protected $_returnTo = null;

    /**
     * The HTTP URL to identify consumer on server
     *
     * @var string
     */
    protected $_root = null;

    /**
     * Extension object or array of extensions objects
     *
     * @var string
     */
    protected $_extensions = null;

    /**
     * The response object to perform HTTP or HTML form redirection
     *
     * @var Zend_Controller_Response_Abstract
     */
    protected $_response = null;

    /**
     * Enables or disables interaction with user during authentication on
     * OpenID provider.
     *
     * @var bool
     */
    protected $_check_immediate = false;

    /**
     * Constructor
     *
     * @param string $id the identity value
     * @param Auth_OpenID_OpenIDStore $storage an optional implementation
     *        of a storage object
     * @param string $returnTo HTTP URL to redirect response from server to
     * @param string $root HTTP URL to identify consumer on server
     * @param mixed $extensions Auth_OpenID_Extension extension object or array of extensions objects
     * @param Zend_Controller_Response_Abstract $response an optional response
     *        object to perform HTTP or HTML form redirection
     * @return void
     */
    public function __construct($id = null,
                                Auth_OpenID_OpenIDStore $storage = null,
                                $returnTo = null,
                                $root = null,
                                $extensions = null,
                                Zend_Controller_Response_Abstract $response = null) {
        $this->_id         = $id;
        $this->_storage    = $storage;
        $this->_returnTo   = $returnTo;
        $this->_root       = $root;
        $this->_extensions = $extensions;
        $this->_response   = $response;

        //нужно потому что автозагрузчик зенда найти не может. там куча классов в одном файле
        require_once 'Auth/OpenID/SReg.php';
        require_once 'Auth/OpenID/PAPE.php';
    }

    /**
     * Authenticates the given OpenId identity.
     * Defined by Zend_Auth_Adapter_Interface.
     *
     * @throws Zend_Auth_Adapter_Exception If answering the authentication query is impossible
     * @return Zend_Auth_Result
     */
    public function authenticate() {

        $id = $this->_id;

        $consumer = new Auth_OpenID_Consumer($this->_storage);

        if (!empty($id)) {

            $authRequest = $consumer->begin($id);

            if (is_null($authRequest)) {
                return new Zend_Auth_Result(
                        Zend_Auth_Result::FAILURE,
                        $id,
                        array("Authentication failed", 'Unknown error'));
            }

            if (Auth_OpenID::isFailure($authRequest)) {
                return new Zend_Auth_Result(
                        Zend_Auth_Result::FAILURE,
                        $id,
                        array("Authentication failed", "Could not redirect to server: " . $authRequest->message));
            }

            $redirectUrl = $authRequest->redirectUrl($this->_root, $this->_returnTo);

            if (Auth_OpenID::isFailure($redirectUrl)) {
                return new Zend_Auth_Result(
                        Zend_Auth_Result::FAILURE,
                        $id,
                        array("Authentication failed", $redirectUrl->message));
            }

            Zend_OpenId::redirect($redirectUrl);

        } else {

            $response = $consumer->complete(Zend_OpenId::selfUrl());

            switch($response->status) {

                case Auth_OpenID_CANCEL:
                case Auth_OpenID_FAILURE:
                    return new Zend_Auth_Result(
                            Zend_Auth_Result::FAILURE,
                            null,
                            array("Authentication failed. " . @$response->message));
                break;

                case Auth_OpenID_SUCCESS:
                    return $this->_constructSuccessfulResult($response);
                break;
            }
        }
    }

    /**
     * @param Auth_OpenID_ConsumerResponse $response
     * @return Zend_Auth_Result
     */
    protected function _constructSuccessfulResult(Auth_OpenID_ConsumerResponse $response)
    {
        $identity = array();

        $identity['openid_identity'] = $response->getDisplayIdentifier();

        if ($response->endpoint->canonicalID) {
            $identity['openid_op_endpoint'] = $response->endpoint->canonicalID;    
        }
        if ($sreg = Auth_OpenID_SRegResponse::fromSuccessResponse($response)) {
            $identity['sreg'] = $sreg->contents();
        }
        if ($pape = Auth_OpenID_PAPE_Response::fromSuccessResponse($response)) {
            $identity['pape'] = (array)$pape;
        }

        return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $identity, array("Authentication successful"));
    }

    /**
     * Sets the storage implementation which will be use by OpenId
     *
     * @param  Auth_OpenID_OpenIDStore $storage
     * @return Smapp_Auth_Adapter_OpenId Provides a fluent interface
     */
    public function setStorage(Auth_OpenID_OpenIDStore $storage)
    {
        $this->_storage = $storage;
        return $this;
    }

    /**
     * Sets the value to be used as the identity
     *
     * @param  string $id the identity value
     * @return Zend_Auth_Adapter_OpenId Provides a fluent interface
     */
    public function setIdentity($id)
    {
        $this->_id = $id;
        return $this;
    }

    /**
     * Sets the HTTP URL to redirect response from server to
     *
     * @param  string $returnTo
     * @return Zend_Auth_Adapter_OpenId Provides a fluent interface
     */
    public function setReturnTo($returnTo)
    {
        $this->_returnTo = $returnTo;
        return $this;
    }

    /**
     * Sets HTTP URL to identify consumer on server
     *
     * @param  string $root
     * @return Zend_Auth_Adapter_OpenId Provides a fluent interface
     */
    public function setRoot($root)
    {
        $this->_root = $root;
        return $this;
    }

    /**
     * Sets OpenID extension(s)
     *
     * @param  mixed $extensions
     * @return Zend_Auth_Adapter_OpenId Provides a fluent interface
     */
    public function setExtensions($extensions)
    {
        $this->_extensions = $extensions;
        return $this;
    }

    /**
     * Sets an optional response object to perform HTTP or HTML form redirection
     *
     * @param  string $root
     * @return Zend_Auth_Adapter_OpenId Provides a fluent interface
     */
    public function setResponse($response)
    {
        $this->_response = $response;
        return $this;
    }

    /**
     * Enables or disables interaction with user during authentication on
     * OpenID provider.
     *
     * @param  bool $check_immediate
     * @return Zend_Auth_Adapter_OpenId Provides a fluent interface
     */
    public function setCheckImmediate($check_immediate)
    {
        $this->_check_immediate = $check_immediate;
        return $this;
    }
}

real world example http://zonabarahla.ru/users/auth/login

source: http://zonabarahla.ru/users/auth/login?show-me-the-truth

is uses http://openidenabled.com/files/php-openid/packages/php-openid-2.1.3.zip

class Users_View_Helper_UsersLinker extends Zend_View_Helper_Abstract
{
    /**
     * @var Zend_View_Helper_Url
     */
    protected static $_urlHelper;

    /**
     * @return Users_View_Helper_UsersLinker
     */
    public function usersLinker()
    {
        return $this;
    }


    public function viewProfile($id) 
    {
        $options = array(
            'controller'    => 'view',
            'action'        => 'profile',
            'id'            => (int)$id
        );
        return $this->_url($options);
    }

    public function viewList()
    {        
        $options = array(
            'controller'    => 'view',
            'action'        => 'list',
        );
        return $this->_url($options);
    }

    public function crudUpdate($id)
    {
        $options = array(
            'controller'    => 'crud',
            'action'        => 'update',
            'id'            => (int)$id
        );
        return $this->_url($options);
    }


    public function login()
    {
        $options = array(
            'controller'    => 'auth',
            'action'        => 'login',
        );
        $url = $this->_url($options);
        return $url;
    }

    public function logout()
    {
        $options = array(
            'controller'    => 'auth',
            'action'        => 'logout'
        );
        return $this->_url($options);
    }

    /**
     * @return Zend_View_Helper_Url
     */
    public function getUrlHelper()
    {
        if (null === self::$_urlHelper) {
            self::$_urlHelper = new Zend_View_Helper_Url();
        }
        return self::$_urlHelper;
    }

    protected function _url($options, $routeName = null, $reset = true)
    {
        $urlHelper = $this->getUrlHelper();
        if (empty($options['module'])) {
            $options['module'] = $this->_getModuleName();
        }

        return $urlHelper->url($options, is_null($routeName) ? 'default' : $routeName, $reset);
    }

    protected function _getModuleName()
    {
        $moduleName = substr(get_class($this), 0, strpos(get_class($this), '_'));
        return strtolower($moduleName);
    }
}


回答2:

The question is old, but I have since implemented OpenID authentication using zfopenid which you can find here:

https://github.com/marcinwol/zfopenid