Goodreads SSO

If you are integrating into a PHP based website other than WordPress, you should start by downloading HybridAuth package from http://hybridauth.sourceforge.net/ .

If you are integrating into a WP site, you should start by installing this plugin: http://wordpress.org/extend/plugins/wordpress-social-login/ it’s based on Hybridauth and as far as I know is coded/maintained by the same developer.

The key to both is the provider script located in hybridauth/Hybrid/Providers folder.

Create a file called Goodreads.php. The name is important, that’s how it will be discovered.

Put this code in it:

<?php
/*!
* HybridAuth
* http://hybridauth.sourceforge.net | https://github.com/hybridauth/hybridauth
*  (c) 2009-2011 HybridAuth authors | hybridauth.sourceforge.net/licenses.html
*/

/**
* Hybrid_Providers_Goodreads
*/
class Hybrid_Providers_Goodreads extends Hybrid_Provider_Model_OAuth1
{
	function initialize()
	{
		parent::initialize();

		// provider api end-points
		$this->api->api_base_url      = "http://www.goodreads.com/";
		$this->api->authorize_url     = "http://www.goodreads.com/oauth/authorize";
		$this->api->request_token_url = "http://www.goodreads.com/oauth/request_token";
		$this->api->access_token_url  = "http://www.goodreads.com/oauth/access_token";

		// turn off json parsing!
		//
		$this->api->decode_json = false;
	}

	function loginFinish()
	{
		if ( !isset($_REQUEST['oauth_token']) || isset( $_REQUEST['authorize'] ) && $_REQUEST['authorize'] == "0" ){
			throw new Exception( "Authentification failed! The user denied your request.", 5 );
		}

		$oauth_verifier = @ $_REQUEST['oauth_token'];

		if ( !$oauth_verifier ){
			throw new Exception( "Authentification failed! {$this->providerId} returned an invalid oauth verifier.", 5 );
		}

		// request an access token
		$tokens = $this->api->accessToken( $oauth_verifier );
		$this->access_tokens_raw = $tokens;

		// check the last HTTP status code returned
		if ( $this->api->http_code != 200 ){
			throw new Exception( "Authentification failed! Goodreads.com returned an error. " . $this->errorMessageByStatus( $this->api->http_code ), 5 );
		}

		// we should have an access_token, or else, something has gone wrong
		if ( ! isset( $tokens["oauth_token"] ) ){
			throw new Exception( "Authentification failed! Goodreads.com returned an invalid access token.", 5 );
		}

		// we no more need to store requet tokens
		$this->deleteToken( "request_token"        );
		$this->deleteToken( "request_token_secret" );

		// sotre access_token for later user
		$this->token( "access_token"        , $tokens['oauth_token'] );
		$this->token( "access_token_secret" , $tokens['oauth_token_secret'] ); 

		// set user as logged in to the current provider
		$this->setUserConnected();
	}

	function getUserProfile()
	{
		$response = $this->api->get( 'http://www.goodreads.com/api/auth_user' );

		// check the last HTTP status code returned
		if ( $this->api->http_code != 200 )
		{
			throw new Exception( "User profile request failed! Goodreads.com returned an error: " . $this->errorMessageByStatus( $this->api->http_code ), 6 );
		}

		// parse the response
		//
		$response = @ new SimpleXMLElement( $response );

		$this->user->profile->identifier  = (string)$response->user['id'];
		$this->user->profile->displayName = (string)$response->user->name;
		$this->user->profile->profileURL  = (string)$response->user->link; 

		return $this->user->profile;
 	}

	function getUserContacts()
	{
		throw new Exception( "Provider does not support this feature.", 8 );
	}

	function getUserActivity( $stream )
	{
		throw new Exception( "Provider does not support this feature.", 8 );
	}

	function setUserStatus( $status )
	{
		throw new Exception( "Provider does not support this feature.", 8 );
	}
}

If you are using Hybridauth API, then change the config file located in hybridauth/config.php to add Goodreads provider to the providers hash:

			"Goodreads" => array (
				"enabled" => true,
				"keys"    => array ( "key" => "MYAPPKEYIGOTFROMGOODREADS", "secret" => "MYAPPSECRETIGOTFROMGOODREADS" )
			),

It goes without saying that you need to put the real values in there and not MYAPP… examples I used.

Now the usage would look something like this:

	require_once( "hybridauth/Hybrid/Auth.php" );

	try{
		// start session if it's not started already
		// we need to pass some stuff between multiple calls
		//
		session_start(); 

		// hybridauth EP
		$hybridauth = new Hybrid_Auth( $config );

		// automatically try to login with goodreads
		$goodreads = $hybridauth->authenticate( "Goodreads" );

		$is_user_logged_in = $goodreads->isUserConnected();

		// get the user profile
		$user_profile = $goodreads->getUserProfile();

		//
		// do something with the profile information
		//

		// logout
		echo "Logging out..";
		$goodreads->logout();
	}
	catch( Exception $e ){
		// do something about the errors
	}

If you are using WSL plugin, then add the following code to the hash in wordpress-social-login/includes/hybridauth.settings.php:

	ARRAY(
		"provider_id" => "Goodreads",
		"provider_name" => "Goodreads",
		"callback" => TRUE,
		"new_app_link" => "http://www.goodreads.com/api",
	)

Callback is not required, but it’s a good idea to put into Goodreads configuration for added security, hence the callback=TRUE flag.

Add Goodreads 16×16 icon into assets/img/16×16 folder as goodreads.png (again the names are important) and Goodreads 32×32 icon into either assets/img/32×32/icondock or assets/img/32×32/wpzoom depending on which set of icons you use, or both to be on the safe side.

Goodreads should be visible as an option in the Settings / WSL Plugin section of WordPress admin. Put the correct values for application key and secret and you should be done.

That’s it folks.

 

Leave a Reply