This is tutorial describes how to authentication web application using Phalcon php and library opauth. We assume that your have basic PHP knowledge including syntax and the concept of PHP object as well Phalcon. You can download full source from github and demo here.

What is opauth ?, according to the official website Opauth as a framework multi-provides a set of API that allows developers to create strategies that work in a predictable manner across PHP frameworks and applications. Opauth interfaces between authentication providers' API and your PHP applications through strategies. Strategies available for Opauth includes Facebook, Google, Twitter, OpenID, and more. How does it work?,as shown in figure below, the Opauth library is the go-between that speaks both phalcon and api google. Besides, You can refer to additional information at here opauth work

Setup project

We are assuming install Phalcon and Phalcon Tools. We’ve successfully set up the development environment. Now we proceed to create the skeleton of our application. Open terminal (in Linux & Mac) or command prompt (cmd in Windows) and type following in the folder where you keep your web projects:

phalcon project opauth

Phalcon have creates following directories which I will explain below:

    opauth/
        app/
            app/config/
            app/controllers/
            app/library/
            app/models/
            app/plugins/
            app/views/
        public/
            public/bootstrap/
            public/css/
            public/js/
        vendor/
            Opauth/

If you have been worked with MVC applications you should be familiar with this structure. We have here an “app” folder, where our application is placed, “public” - where your static files will land, and vendor which is just a directory for external classes, in this case library opauth.

Implementing Opauth with Phalcon

To do that, download Opauth in github and unzip it. Then copy folder into your directory, in this case "opauth/vendor/Opauth/". Remember to name the directory name as the actual name of the strategy. Place Google strategy files in vendor/Opauth/Strategy/Google so that GoogleStrategy.php can be found at vendor/Opauth/Strategy/Google/GoogleStrategy.php, for example.

Let's analyze this the Opauth configuration of phalcon, for instance review config.php file.

   return new \Phalcon\Config(array(
            'database' => array(
                'adapter' => 'Mysql',
                'host' => 'localhost',
                'username' => 'root',
                'password' => 'password',
                'dbname' => 'sendmail',
            ),
            'application' => array(
                'controllersDir' => __DIR__ . '/../../app/controllers/',
                'modelsDir' => __DIR__ . '/../../app/models/',
                'viewsDir' => __DIR__ . '/../../app/views/',
                'pluginsDir' => __DIR__ . '/../../app/plugins/',
                'libraryDir' => __DIR__ . '/../../app/library/',
                'cacheDir' => __DIR__ . '/../../app/cache/volt/',
                'baseUri' => '/opauth/',
                'publicUrl' => '127.0.0.1/sendmail',
                'debug' => '0',
            ),
            'opauth'=>array(
                'path' => '/opauth/session/loginOpauth/',
                'callback_url' => 'http://localhost/opauth/session/success/',
                //'callback_transport' => 'post',
                'security_salt' => 'LDFmiilYf8Fyw5W10aaaaarx4W1KsVrieQCnpBzzpTBWA5vJidQKDx8pMJbmw28R1C4m',
                'debug' =>true,

                'Strategy'=>array(
                    'Facebook' =>array(
                    ),
                    'Google' =>array(
                        'client_id'   =>'378342860757-u41bhknu4mvt459gqkj451gt32gret8k.apps.googleusercontent.com',
                        'client_secret'   =>'nF0-qgZIt6IjlLzEPuTiZVaI',
                        //'redectUrl' =>'http://opauth.duythien.com/session/abc',
                    ),
                    'Twitter' =>array(
                    'key' =>'fz8titsIrWJjeNdkR7d0w',
                    'secret' =>'66hqNnIyMkW84lp4f7XmcKGAJQk1ffrT2wIyIxP6mQ',
                    ),
                ),
            ),
        ));

Here are parameter Strategy must to is array. The one important in configure file above that are keyword Google, Facebook,etc need to exactly, also see Opauth configuration here . In this case We use Google so you must setup api google. You also see here.

Let's analyse the structure of parameter Strategy.

  • path (string) Path where Opauth is accessed, if Opauth is reached via http://localhost/opauth/, path should be set to '/opauth/'
  • security_salt: string A random string used for signing of
  • callback_url : string URL where Opauth sends auth response to, successful or otherwise, the default value '{path}callback.php'
  • callback_transport: defines how you handle the response. It defaults to session. Since Phalcon does use native sessions,I’ve comment for the callback transport. You can use session, get, or post for this parameter.
  • debug: (boolean) Whether debug messages are to be displayed

Besides. You can refer additional information about variable at https://github.com/opauth/opauth/wiki/Opauth-configuration

The next, We create the Auth class in the folder library(app/libarary/Auth.php) with the contents as follows.

    use Phalcon\Mvc\User\Component,
        Phalcon\Mvc\View;

    require_once __DIR__ . '/../../vendor/Opauth/Opauth.php';
    /**
     *
     * Authenticaton based on pre-defined paramater
     */
    class Auth extends Component
    {
        /**
         * paramater array
         */

        protected $paramater;


        //Login with account google and more
        public function login()
        {

            $this->paramater = $this->objectToArray($this->config->opauth);

            if (is_array($this->paramater)) {
            $paramater = $this->paramater;
            }

            $opauth = new Opauth($paramater);

            $opauth->run();
        }
        /**
         * Convert  object into array
         * @param   $object is object
         * @return  array
         */
        public function objectToArray($object)
        {
            if(!is_object($object) && !is_array($object))
            {
                return $object;
            }
            if(is_object($object))
            {
                $object = get_object_vars( $object );
            }
            return array_map(array($this,"objectToArray"), $object );
        }
    }=

We've defined two functions, the first function login on duty called class in the core Oauth library with the configurations and call the run() method. It will automatically identify the requested strategy through the URL and redirect the user for authentication. The second function is object Array to convert object into array because of parameter received at Phalcon is object, not a array.

In above We have used run() method for Oauth class, We are review it right now

    public function run(){
        $this->parseUri();

        if (!empty($this->env['params']['strategy'])){
            if (strtolower($this->env['params']['strategy']) == 'callback'){
                $this->callback();
            }
            elseif (array_key_exists($this->env['params']['strategy'], $this->strategyMap)){
                $name = $this->strategyMap[$this->env['params']['strategy']]['name'];
                $class = $this->strategyMap[$this->env['params']['strategy']]['class'];
                $strategy = $this->env['Strategy'][$name];

                // Strip out critical parameters
                $safeEnv = $this->env;
                unset($safeEnv['Strategy']);

                $actualClass = $this->requireStrategy($class);
                $this->Strategy = new $actualClass($strategy, $safeEnv);

                if (empty($this->env['params']['action'])){
                    $this->env['params']['action'] = 'request';
                }
                $this->Strategy->callAction($this->env['params']['action']);
            }
            else{
                trigger_error('Unsupported or undefined Opauth strategy - '.$this->env['params']['strategy'], E_USER_ERROR);
            }
        }
        else{
            $sampleStrategy = array_pop($this->env['Strategy']);
            trigger_error('No strategy is requested. Try going to '.$this->env['complete_path'].$sampleStrategy['strategy_url_name'].' to authenticate with '.$sampleStrategy['strategy_name'], E_USER_NOTICE);
        }
    }

Handling the Open Auth Response

Next, We are created a new file with called name SessionController.php.

    <?php

    class SessionController extends ControllerBase
    {
        public function loginOpauthAction()
        {
            $this->session->set('opauth',$this->auth->login());
        }
        public function successAction()
        {
             $this->view->auths = $this->session->get('opauth');
             //var_dump($result);
         //$this->view->disable();
        }

In this file, we define two functions loginOpauthAction and successAction, the first function set session in app after click login button such as Google+ with name is opauth , the second function get session and assign paramater auth And render template in view after login validate success(success.volt)

        {{content()}}
        <div>

        <section>
            <h2>Authentication sucessful</h2>
            <p>Authentication is successful and auth response is <span>validated</span>.</p>

            <p>Returned auth response:</p>

            <table class="table">
            <tbody>
            <tr>
                <th>Key</th>
                <th>Value</th>
            </tr>
            {% for key,auth in auths['auth'] %}
                {% if auth is scalar %}
                    <tr>
                    <th> {{key }}</th>
                    <th> {{auth}} </th>
                    </tr>
                {% else %}
                    <tr>
                    <th> {{key}} </th>
                    <td><ul>
                    {% for key1,item in auth %}
                            {% if key1 is sameas('image') %}
                                <li><strong>{{key1}}</strong>:<img src="{{item}}" width="100" height="100"> </li>
                            {% elseif key1 == 'urls' %}
                                <li><strong>{{key1}}</strong>: {{item['google']}} </li>
                            {% else %}
                            <li><strong>{{key1}}</strong>: {{item}} </li>
                            {% endif %}
                    {% endfor %}
                    </ul></td>
                    </tr>
                {% endif %}
            {% endfor %}
            </tbody>
            </table>
            <h2>Raw response</h2>
                {{"<pre>"}}
                <?php print_r($auths);?>
              </section>
            </div>

Let’s assume that the user clicked the Google login link. This is result should be look like images below

opauth-result

For now, we are going to see parameter Auth response is the PHP array resulted from successful authentication with Opauth, here for example.

  • provider (required) - The provider with which the user authenticated (e.g. 'Google' or 'Facebook')
  • uid (required) - An identifier unique to the given provider, such as a Google user ID.
  • info (required) - An array containing information about the user, such as name, email, image, etc.
  • credentials - If the authenticating service provides some kind of access token or other credentials upon authentication, these are passed through here.
  • raw - An array of all information gather about a user. It should be converted to array before returning to the user.
  • timestamp - Time (in ISO 8601 format) when this auth was prepared. Used as a security measure against security_timeout.
  • signature - A signature by Opauth to ensure that the enclosed data in this response is valid and unaltered. See Security in Opauth for more info.

In this case error response

Upon authentication error, Opauth sends the following auth response to callback_url.

  • (required) - A wrapper of error response such as provider (required) is the provider with which the user authenticated (e.g. 'Twitter' or Google), raw, code, etc.
  • timestamp - Time (in ISO 8601 format) when this error response was prepared.
  • Note that no signature is generated for error response.

In Conclusion

In this article, We discussed how to integrate Opauth with Phalcon, you can use it so that into your application such as authentication before allowing it comment. As you can see, use of that library is so simple and fast.

For more information on Phalcon check out the online documentation and opauth docmument here. Thanks for reading – leave your feedback and comments below.