1

I am working on a web application that, among other things, reads the gmail of a signed in user. I am using the Google PHP library to handle authentication, and I am able to fetch emails without problems. The problem is that the access token expires after 1 hour. The documentation indicates that you should get a refresh token with the initial authorization, but when I call $client->getRefreshToken(), it returns null.

I understand that the refresh token is only returned the first time that a user signs in. While testing this, I revoked the authorization on the account, and then tried again, but it still does not give me a refresh token. What am I doing wrong?

Edit: I had a friend sign in with his personal Google account, which has never been used on the site, and still, no refresh token was given.

Source code:

Login.php: The first page

<?php
session_start();
require_once 'vendor/autoload.php';
$force=(isset($_GET['force'])&&$_GET['force']='true');
if(!isset($_SESSION['google_token'])||force)
{
    $client=new Google_Client();
    $client->setAuthConfig('/path/to/client_secret.json');
    $client->addScope('https://www.googleapis.com/auth/gmail.readonly');
    $client->addScope('https://www.googleapis.com/auth/userinfo.email');
    $client->addScope('https://www.googleapis.com/auth/userinfo.profile');
    $client->setState('offline'); //I realized that the mistake is here, see my answer below.
    $client->setApprovalPrompt('force');
    if($force)
            $client->setPrompt('consent');
    $client->setRedirectUri('https://example.com/doLogin.php');

    $auth_url=$client->createAuthUrl();
    header("Location: " . filter_var($auth_url, FILTER_SANITIZE_URL));
    die();
}
header('location: /index.php');
die();

doLogin.php: The Google Oauth page redirects here.

<?php
session_start();
require_once 'vendor/autoload.php';
if(isset($_GET['error']))
{
    session_unset();
    header('location: /error.php?error='.urlencode('You must be signed into Google to use this program.'));
    die();
}
$client=new Google_Client();
$client->setAuthConfig('/path/to/client_secret.json');
$client->setRedirectUri('https://example.com/doLogin.php');
$client->setAccessType('offline');
$client->authenticate($_GET['code']);
$access_token=$client->getAccessToken();
$refresh_token=$client->getRefreshToken();

$service=new Google_Service_Oauth2($client);
$email=$service->userinfo->get()['email'];
$_SESSION['email']=strtolower($email);

$_SESSION['access_token']=$access_token;
$_SESSION['refresh_token']=$refresh_token;
header('Location: /index.php');
die();
?>
BillThePlatypus
  • 332
  • 1
  • 9

1 Answers1

1

OK, so after looking around, and poking through the raw http, I found my mistake. I was calling $client->setState('offline'); instead of $client->setAccessType('offline'); I fixed that, and now I am receiving the refresh token when I should.

BillThePlatypus
  • 332
  • 1
  • 9