There’s a lovely Codeigniter Spark by Phil Sturgeon which does OAuth2 login for Facebook and GitHub and Windows Live. The spark is here. I’d set it up for Facebook a month ago, on our dev site for the Community Media Project. Then yesterday and this morning I checked the spark again, still no Google auth, so I decided to write that. After all a Google+ or Facebook account covers most people, and it feels less proprietary than just offering Facebook as a login.

So I wrote it. The code is here – it’s just a provider class which hooks into the OAuth2 framework. The only tricky bit was that Google uses POST to get the authorization token, so I chose to do that bit with cURL. DON’T TRY TO USE THIS CODE – see below for why.

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class OAuth2_Provider_Google extends OAuth2_Provider {  
	public $name = 'google';

	public $uid_key = 'uid';
	
	public $scope = 'https://www.googleapis.com/auth/userinfo.profile';
	
	const google_redirect_uri = 'http://<something something>/auth/';


	public function __construct($options = null) {
		parent::__construct($options);
		$this->redirect_uri = self::google_redirect_uri;
	}
	
	public function url_authorize(){
		return 'https://accounts.google.com/o/oauth2/auth';
	}

	public function url_access_token(){
		return 'https://accounts.google.com/o/oauth2/token';
	}
	
	public function access($code) {
		$fields = array(
			'code'		=> $code,
			'client_id'	=> $this->client_id,
			'client_secret' => $this->client_secret,
			'redirect_uri'	=> 'http://newscollab.com/auth/',
			'grant_type'	=> 'authorization_code'
		);
		$fieldstring = http_build_query($fields);
		$curl = curl_init();
		curl_setopt($curl, CURLOPT_URL, $this->url_access_token());
	    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	    curl_setopt($curl, CURLOPT_POST, count($fields));
	    curl_setopt($curl, CURLOPT_POSTFIELDS, $fieldstring);
	    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	    $response = curl_exec($curl);
	    curl_close($curl);
		return json_decode($response, true);
	}

	
	public function get_user_info($token){
		$url = 'https://www.googleapis.com/oauth2/v1/userinfo?'.http_build_query(array(
			'access_token' => $token,
		));
		$user = json_decode(file_get_contents($url));
		return get_object_vars($user);
	}
}

So far so good. But now, belatedly, I’ve just looked at the github repository for that spark, and sure enough someone beat me to it. I could have saved a few hours by doing the basic checking more carefully before I started.

It does look like they’ve picked a slightly different approach, based on the fact that there has been some good improvement in the original spark. The constructor is cleaned up and the provider superclass now decides whether to GET or POST the token collection. That makes the code above out of date.

Sigh. Well, it was fun, anyway.