Skip to content

Strategy contribution guide

Fred Delrieu edited this page Oct 21, 2013 · 7 revisions

Before writing your own Opauth strategy, you might want to check out the list of strategies to see if it is already created, or if the existing one fits your requirement.

To start, you might want to refer to Google strategy as a guide.

For this example, let's assume that we are creating a strategy for Foo.

  1. Naming conventions

Name your class FooStrategy and extends OpauthStrategy.

Suggestion: If you are hosting it on a public GitHub repository, it is suggested that the repository be named opauth-foo.

If you are creating a strategy for FooBar, name the class FooBarStrategy and the repository opauth-foobar.

  1. List the configuration requirements

There are 3 key configuration types:

expects - Compulsory config keys, listed as unassociative arrays optionals - Optional config keys, without predefining any default values. defaults - Optional config keys with respective default values, listed as associative arrays.

Example:

<?php
class FooStrategy extends OpauthStrategy{
    /**
     * Compulsory config keys, listed as unassociative arrays
     */
    public $expects = array('client_id', 'client_secret');
    
    /**
     * Optional config keys, without predefining any default values.
     */
    public $optionals = array(
        'redirect_uri', 'scope', 'state', 'access_type', 'approval_prompt'
    );
    
    /**
     * Optional config keys with respective default values, listed as associative arrays
     * eg. array('scope' => 'email');
     */
    public $defaults = array(
        'redirect_uri' => '{complete_url_to_strategy}oauth2callback',
        'scope' => 'https://www.googleapis.com/auth/userinfo.profile'
    );
}
  1. Helpers

The following properties are inherited from OpauthStrategy and might be useful to your when developing your very own strategy.

  • $strategy (protected): Configurations and settings unique to a particular strategy
    Settings and configurations related to a strategy is contained in this array.

  • $env (protected): Filtered environmental values from Opauth.
    Configurations and environmental values for Opauth core are available here for reference only. Altering any values here will not alter the actual env values of Opauth core.

Opauth also include a library of methods for making simple HTTP calls. The notable methods are:

  • redirect() - simple client-side redirect.
  • clientGet() - client-side GET request
  • clientPost() - client-side POST request
  • serverGet() - server-side GET request
  • serverPost() - server-side POST request

They are mainly wrappers of file_get_contents(). You are strongly encouraged to use them if possible to avoid introducing unnecessary requirements to your strategy. However, if you require more sophisticated HTTP requests, feel free to bundle your own HTTP library with your strategy.

Refer to Opauth Strategy API for full documentation on these methods.

  1. Methods

The only mandatory method for an Opauth strategy is public function request(). This is the function that handles the authentication with the authentication provider.

You are free to include other methods if the authentication process requires several round-trips. By declaring a method public, it will be reachable directly through HTTP via http://path_to_opauth/STRATEGY/METHOD_NAME.

Avoid any hardcodings of internal URLs and links. To obtain the internal callback URL to reach, say public function oauthcallback(), use {complete_url_to_strategy}oauthcallback (when declaring $defaults) or $this->strategy['complete_url_to_strategy'].oauthcallback in methods.

Any unnamed actions or methods that are not available will automatically be handled by public function request().

  1. Callbacks

###Success Upon successful authentication, a strategy is to prepare nicely formatted auth response and call $this->callback().

<?php
$this->auth = array(
    'provider' => 'Foo',
    'uid' => 1643816165,
    'info' => array(
        'name' => 'John Doe',
        'email' => '[email protected]',
        'first_name' => 'John',
        'last_name' => 'Doe',
        // etc...
    ),
    'credentials' => array(
        'token' => '2983749283kjnadfkjiuh2',
        'secret' => 'if any',
        'expires' => date('c', strtotime('token expiry'))
    ),
   'raw' => '(any raw user data)'
);

$this->callback();

Please refer to auth response for more details.

###Error handling Upon encountering any errors, call $this->errorCallback($error); where $error is of the following format:

<?php
$error = array(
    'provider' => 'Foo',
    'code' => 'access_token_error',
    'message' => 'Failed when attempting to obtain access token',
    'raw' => array(
        // Raw data does not have any fixed format, you should supply any
        // raw data that you think will be able to help diagnose the issue
        'response' => $response,
        'headers' => $headers
    )
);

$this->errorCallback($error);
  1. Done

That is basically it.

If you feel like sharing your newly created strategy, let us know at Opauth's Google Groups.

###Composer (optional) If your strategy is Composer-compatible, feel free to submit it to Packagist and name it opauth/foo for FooStrategy.

Here's a sample composer.json for your reference:

{
    "name": "opauth/foo",
    "description": "Foo strategy for Opauth",
    "keywords": ["authentication","auth","opauth","foo"],
    "homepage": "http://opauth.org",
    "license": "MIT",
    "authors": [
        {
            "name": "U-Zyn Chua",
            "email": "[email protected]",
            "homepage": "http://uzyn.com"
        }
    ],
    "require": {
        "php": ">=5.2.0",
        "opauth/opauth": ">=0.2.0"
    },
    "autoload": {
        "psr-0": {
            "": "."
        }
    }
}