Welcome Guest, Not a member yet? Register   Sign In
Codeigniter + OAuth + Google Data
#1

[eluser]hotmeteor[/eluser]
Part 1.

I think this topic is one of great annoyance, judging by the confusion and hardship all around the net surrounding people's efforts to get OAuth and Google Data working. I was one of these unfortunates, until last night.

At first I tried Jamie Rumbelow's Codeigniter OAuth library. It works great for OAuth+Twitter (which it was written for), but despite fiddling with it for 4 hours I couldn't get it working with Google. I was then forced to integrate the OAuth-PHP library. It's full-on, but the documentation is pretty weak right now.

Anyway, this is what I used to get it going, so I thought I'd share my implementation. Please feel free to comment how I can refactor my code, but bear in mind that I just got this working satisfactorily so I've yet to arrange everything to my liking.

Without further adieu:
--------------------------

SETUP + INSTALLATION
1. Register your application at Google. You don't have to, but it's nicer. Once you're registered you'll get a consumer key and a secret key.
2. Get the OAuth-PHP library, as noted above.
3. Drop the library folder into your application's libraries folder. I renamed this folder to OAuth.
4. There's an SQL file in the store subfolder; import it into your database.
5. Important: Because Google uses secure URLs (https://) for their OAuth, in order to connect with Google you need to modify the OAuthRequester.php file in one place.

OAuthRequester.php, line 397 (below the cURL options), add this:
Code:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
#2

[eluser]hotmeteor[/eluser]
Part 2.

You're now ready to start getting this thing going. For my example, I have two controllers: Oauth.php (which does the OAuth-ing) and Analytics.php (which does the stuff I'm authorized to do).

OAuth.php
Code:
<?php
/**
* OAuth controller
*/
class Oauth extends Controller
{    
    function Oauth()
    {
        parent::Controller();
    }
    
    function index()
    {
        // include the OAuth library.        
        include_once APPPATH . "libraries/Oauth/OAuthStore.php";
        include_once APPPATH . "libraries/Oauth/OAuthServer.php";
        include_once APPPATH . "libraries/Oauth/OAuthRequester.php";
        
        // Get the id of the current user (must be an int)
        $user_id = $this->session->userdata('user_id');
        
        // Initiate the store.
        $options = array('server' => $this->db->hostname, 'username' => $this->db->username, 'password' => $this->db->password, 'database' => $this->db->database);
        $store   = OAuthStore::instance('MySQL', $options);
        
        // Google
        $consumer_key = 'example_key'; // fill with your public key
        $consumer_secret = 'example_secret'; // fill with your secret key
        $server_uri = "https://www.google.com"; // fill with the url for the oauth service
        $request_uri = "https://www.google.com/accounts/OAuthGetRequestToken";
        $authorize_uri = "https://www.google.com/accounts/OAuthAuthorizeToken";
        $access_uri = "https://www.google.com/accounts/OAuthGetAccessToken";
            
        // The server description
        $server_data = array(
            'consumer_key' => $consumer_key,
            'consumer_secret' => $consumer_secret,
            'server_uri' => $server_uri,
            'signature_methods' => array('HMAC-SHA1', 'PLAINTEXT'),
            'request_token_uri' => $request_uri,
            'authorize_uri' => $authorize_uri,
            'access_token_uri' => $access_uri
        );
        
        // Check if this consumer is on this server.
        $servers = $store->listServers($server_uri, $user_id);
        
        if(empty($servers))
        {
            // Save the server in the the OAuthStore
            $consumer_key = $store->updateServer($server_data, $user_id);
        }        
        
        // Obtain a request token from the server (scope is required)
        $token = OAuthRequester::requestRequestToken($consumer_key, $user_id, array('scope' => 'https://www.google.com/analytics/feeds/'), 'GET' );
        
        // Callback to our (consumer) site, will be called when the user finished the authorization at the server
        $callback_uri = 'http://yoursite.com/oauth/callback?consumer_key='.rawurlencode($consumer_key).'&usr;_id='.intval($user_id);
        
        // Now redirect to the autorization uri and get us authorized
        if (!empty($token['authorize_uri']))
        {
            // Redirect to the server, add a callback to our server
            if (strpos($token['authorize_uri'], '?'))
            {
                $uri = $token['authorize_uri'] . '&';
            }
            else
            {
                $uri = $token['authorize_uri'] . '?';
            }
            $uri .= 'oauth_token='.rawurlencode($token['token']).'&oauth;_callback='.rawurlencode($callback_uri);
        }
        else
        {
            // No authorization uri, assume we are authorized, exchange request token for access token
           $uri = $callback_uri . '&oauth;_token='.rawurlencode($token['token']);
        }
        
        header('Location: '.$uri);
        exit();
    }
    
    function callback()
    {
        // include the OAuth library.        
        include_once APPPATH . "libraries/Oauth/OAuthStore.php";
        include_once APPPATH . "libraries/Oauth/OAuthServer.php";
        include_once APPPATH . "libraries/Oauth/OAuthRequester.php";
        
        // Initiate the store.
        $options = array('server' => $this->db->hostname, 'username' => $this->db->username, 'password' => $this->db->password, 'database' => $this->db->database);
        $store   = OAuthStore::instance('MySQL', $options);
        
        // Request parameters are oauth_token, consumer_key and usr_id.
        $consumer_key = $_GET['consumer_key'];
        $oauth_token = $_GET['oauth_token'];
        $user_id = $_GET['usr_id'];
        
        try
        {
            OAuthRequester::requestAccessToken($consumer_key, $oauth_token, $user_id);
        }
        catch (OAuthException $e)
        {
            // Something wrong with the oauth_token.
            // Could be:
            // 1. Was already ok
            // 2. We were not authorized
            echo 'catch';
        }
    }
}

/* End of file oauth.php */
/* Location: ./system/application/controllers/oauth.php */
#3

[eluser]hotmeteor[/eluser]
Part 3.

Lastly, this is how you make a request based on a saved access token. When someone authorizes their account, the token is saved in your DB. Now we have it and can use it! (note: this bit is a slightly more rough at this point).

Code:
<?php
/**
* Analytics controller
* Connects to Google Analytics.
*/
class Analytics extends Controller
{    
    function Analytics()
    {
        parent::Controller();
    }
    
    function index()
    {
        $user_id = $this->session->userdata('user_id');
        
        // include the OAuth library.        
        include_once APPPATH . "libraries/Oauth/OAuthStore.php";
        include_once APPPATH . "libraries/Oauth/OAuthServer.php";
        include_once APPPATH . "libraries/Oauth/OAuthRequester.php";
        
        // Initiate the store.
        $options = array('server' => $this->db->hostname, 'username' => $this->db->username, 'password' => $this->db->password, 'database' => $this->db->database);
        $store   = OAuthStore::instance('MySQL', $options);
        
        // Google
        $consumer_key = 'example_key'; // fill with your public key
        $consumer_secret = 'example_secret'; // fill with your secret key
        $server_uri = "https://www.google.com"; // fill with the url for the oauth service
        $request_uri = "https://www.google.com/accounts/OAuthGetRequestToken";
        $authorize_uri = "https://www.google.com/accounts/OAuthAuthorizeToken";
        $access_uri = "https://www.google.com/accounts/OAuthGetAccessToken";
            
        // The server description
        $server_data = array(
            'consumer_key' => $consumer_key,
            'consumer_secret' => $consumer_secret,
            'server_uri' => $server_uri,
            'signature_methods' => array('HMAC-SHA1', 'PLAINTEXT'),
            'request_token_uri' => $request_uri,
            'authorize_uri' => $authorize_uri,
            'access_token_uri' => $access_uri
        );
        
        // Check if this consumer is on this server.
        $servers = $store->listServers($server_uri, $user_id);
        
        // They're not...
        if(empty($servers))
        {
            // Save the server in the the OAuthStore
            //$consumer_key = $store->updateServer($server_data, $user_id);
            
            echo "You're not authenticated yet. Want to be?";
        }
            
        // They are! Let's get Analytical.
        else
        {
            // But first, we check if they have an access token.
            $token = $store->getSecretsForSignature($server_uri, $user_id);
            if( ! $token)
            {
                echo 'no';
            }
            else
            {
                // Check to see if user has been authorized.
                // The request uri being called.
                
                // Parameters, appended to the request depending on the request method.
                // Will become the POST body or the GET query string.
                $params = array();
                
                // Obtain a request object for the request we want to make
                $req = new OAuthRequester($server_uri, 'GET', $params);
                
                // Sign the request, perform a curl request and return the results, throws OAuthException exception on an error
                $result = $req->doRequest($user_id);
                echo '<pre>' . print_r($result, TRUE) . '</pre>';
                
                // $result is an array of the form: array ('code'=>int, 'headers'=>array(), 'body'=>string)
            }
        }
    }
}

/* End of file analytics.php */
/* Location: ./system/application/controllers/analytics.php */

That's it! I'll answer any questions I can.
#4

[eluser]totels[/eluser]
Unsure if it is a quirk of the code display on these forums or an error in your code but there are some extraneous semicolon characters, looks like something was trying to create HTML escape characters in URI strings

Oauth.php
Code:
$callback_uri = 'http://yoursite.com/oauth/callback?consumer_key='.rawurlencode($consumer_key).'&usr;_id='.intval($user_id);
//                                                                                                  ^-here
Code:
$uri .= 'oauth_token='.rawurlencode($token['token']).'&oauth;_callback='.rawurlencode($callback_uri);
//                                                          ^-here
Code:
$uri = $callback_uri . '&oauth;_token='.rawurlencode($token['token']);
//                            ^-here
#5

[eluser]totels[/eluser]
I think you are also using a MY_Input.php adjustment and configuration to allow GET strings in the URL. You may want to explain where you got it and how to configure it as the code you provide won't work "out of the box".

for reference:
http://ellislab.com/forums/viewthread/56389/#277621
http://tohin.wordpress.com/2009/04/05/co...to-gether/
http://gist.github.com/299138
#6

[eluser]Ki[/eluser]
Has anybody looked at integrating php oAuth extension?

I have started with this:
Code:
function yt_token(){

        $oauth = new OAuth(GOOGLE_OAUTH_CONSUMER_KEY,GOOGLE_OAUTH_CONSUMER_SECRET,OAUTH_SIG_METHOD_HMACSHA1,OAUTH_AUTH_TYPE_URI);
        $scope = urlencode("https://gdata.youtube.com");
        preg_match("/(oauth_token=)(.*)/",$_SERVER['REQUEST_URI'],$result);

        // if we need to do a master reset on tokesn, delete the youtube_request_token
        if(!isset($result['2'])){
            $response = $oauth->getRequestToken(GOOGLE_OAUTH_REQUEST_TOKEN_API."?scope=".$scope);
            file_put_contents(OAUTH_TMP_DIR . "/youtube_request_token",serialize($response));
            $oauth_callback = urlencode('http://'.SUB.'.samotaka.bg'.$_SERVER['REQUEST_URI']);
            header('Location: '.GOOGLE_OAUTH_AUTHORIZE_API.'?oauth_token='.$response['oauth_token'].'&oauth;_callback='.$oauth_callback);
        }
        else{
            $request_token = unserialize(file_get_contents(OAUTH_TMP_DIR . "/youtube_request_token"));
            $oauth->setToken($request_token['oauth_token'],$request_token['oauth_token_secret']);
            print_r($result);
            print_r($request_token);
            
            $response = $oauth->getAccessToken(GOOGLE_OAUTH_ACCESS_TOKEN_API);
            file_put_contents(OAUTH_TMP_DIR . "/youtube_access_token",serialize($response));

        }
    }
#7

[eluser]Ehsan-ul-haq[/eluser]
hey

i implement this code great work ,


i just want to know one question

when i use this

i get this message

Update: the privacy policy has been simplified and updated. Learn more.

You have successfully granted openid4u.iehsan.com access to your Google Account. You can revoke access at any time under 'My Account'.


you may check with this link
http://openid4u.iehsan.com/index.php/oauth

but how can i use callback to my site after this message ?



thanks
#8

[eluser]totels[/eluser]
[quote author="Ehsan-ul-haq" date="1284840924"]but how can i use callback to my site after this message ?[/quote]
The most common method is to use the callback_uri, possibly combined with the GET string variables. Another popular method is to do the authentication in a popup window and use a JS setTimeout to wait for the popup to close(this method only tells you that the window closed, not if the authentication was successful or not).
#9

[eluser]Ehsan-ul-haq[/eluser]
hi

ok

please check my given link that will help to understand my problem or question

i think u talking about these lines if i am not wrong

// Obtain a request token from the server (scope is required)
$token = OAuthRequester::requestRequestToken($consumer_key, $user_id, array('scope' => 'https://www.google.com/m8/feeds/'), 'GET' );


// Callback to our (consumer) site, will be called when the user finished the authorization at the server
$callback_uri = 'http://openid4u.iehsan.com/index.php/callback?consumer_key='.rawurlencode($consumer_key).'&usr;_id='.intval($user_id);

thanks
for treply
#10

[eluser]totels[/eluser]
[quote author="Ehsan-ul-haq" date="1284843000"]
// Callback to our (consumer) site, will be called when the user finished the authorization at the server
$callback_uri = 'http://openid4u.iehsan.com/index.php/callback?consumer_key='.rawurlencode($consumer_key).'&usr;_id='.intval($user_id);
[/quote]

Yes, based on this the authenticating user would be redirected back to "http://openid4u.iehsan.com/index.php/callback" you can then do any processing or redirecting of your own from your callback function.




Theme © iAndrew 2016 - Forum software by © MyBB