yasirsiddiqui / php-google-cloud-print

PHP class to print documents using Google Cloud Print with OAuth2 authorization
91 stars 42 forks source link

Token Refresh #7

Closed JamesSimpson closed 9 years ago

JamesSimpson commented 9 years ago

How can we add a token refresh to this, so it can be ran from a cron job instead of manual auth every time

yasirsiddiqui commented 9 years ago

Right now it does not supports token refresh. I will add this feature near future.

JamesSimpson commented 9 years ago

Perfect, that would be great as I would like to keep this code as standard as possible for future updates, while keeping my side of things the same.

StartFitness commented 9 years ago

We could do with this exact same feature - how long would it take you to implement this do you reckon?

JamesSimpson commented 9 years ago

Yasir, how long do you recon it would take you to implement this? I would give it a go myself, but I don't want to mess up your code.

yasirsiddiqui commented 9 years ago

James i am planing to implement this on coming weekend. If you want to give it a try then go ahead and implement it.

bigware commented 9 years ago

I got it working with server side. Let me know if you want to know what I did.

der-lukas commented 9 years ago

I want to know! ;)

bigware commented 9 years ago

Obviously, you will need to create a Client ID for a service account using the same email account that has the printers. Set it up using P12 key and save the download give you.

Next, I included the google-api-php-client library into my code. You can download the latest release here: https://github.com/google/google-api-php-client/releases You need the "google" folder in the src folder only Include autoload.php in the goolge folder into your project.

Next, when I used "$gcp->loginToGoogle()" in the past version, I set to $gcp->setAuthToken(google_cloud_print_get_auth_token()); and created a function that got the auth token every time. Theoretically, you can store it for an hour, but I dont do that much printing, and dont want to test it everytime.

Here is the function I created:

function google_cloud_print_get_auth_token()
{
    global $settings;

    $credentials = new Google_Auth_AssertionCredentials(
        $settings['google_cloud_print_client_email'],
        array('https://www.googleapis.com/auth/cloudprint'),
        $settings['google_cloud_print_private_key'],
        'notasecret',                                 // Default P12 password
        'http://oauth.net/grant_type/jwt/1.0/bearer', // Default grant type
        $settings['google_cloud_print_email']
    );

    $client = new Google_Client();
    $client->setAssertionCredentials($credentials);
    if ($client->getAuth()->isAccessTokenExpired())
    {
        $client->getAuth()->refreshTokenWithAssertion();
    }
    return json_decode($client->getAuth()->getAccessToken())->access_token;
}

I put the client_email, private_key file, email address direct into my project settings. $settings['google_cloud_print_client_email'] replace with the Email address posted under the "Service account" credentials $settings['google_cloud_print_private_key'] is the P12 file contents. I used a blob in my database to store it, but you also use php's file_get_contents function if you want to keep as file on your server $settings['google_cloud_print_email'] gets changed to your actual email address.

I wrote this up a little messy. Let me know f you have any questions.

yasirsiddiqui commented 9 years ago

I have added offline support in simple way. Now you can use the script in offline mode or printing documents using cron job where user is not present.

bigware commented 9 years ago

Seems to be working. I wish you had this 2 days so I didn't sweat over nothing. The only advantage my way has is that it doesn't ever need you to authenticate. I'm just implemented your way though. I ll have to manually retrieve the code again if there is an issue.

JWTom commented 9 years ago

My goal is to have a list of MY printers available on a private website for all of my internal users without them having the printers "shared" to them or having to login to Google. Would the refresh token be a good solution for this or is it intended only as a cron (print later) method?

bigware commented 9 years ago

Yes, the system for cron would work for that. I would suggest for you to build in a way for you to refresh that token, since Google can revoke it at their discretion. My solution above would save you from that though, as its a solution to be used directly for one google account, and never needs a token through a browser.

JWTom commented 9 years ago

Thank you for your response. I am getting this error: Fatal error: Uncaught exception 'Exception' with message 'Please first login to Google' in ...../GoogleCloudPrint.php:120 Stack trace: #0 ...cron.php(35): GoogleCloudPrint->getPrinters() #1 {main} thrown in .../GoogleCloudPrint.php on line 120

This is only when attempting offline mode. Any clue what I may be doing wrong?

JWTom commented 9 years ago

I figured it out!! I was passing values improperly. This code works as it should. Very nice work!