googleapis / google-api-php-client

A PHP client library for accessing Google APIs
http://googleapis.github.io/google-api-php-client/
Apache License 2.0
9.28k stars 3.52k forks source link

authenticate() accepts invalid tokens #398

Closed haimat closed 9 years ago

haimat commented 9 years ago

The following code does work for me without any error, it gives me all user details:

/* Verify Google session. */
$client = new Google_Client();
$client->setAccessType('online');
$client->setClientId(GOOGLE_CLIENT_ID);
$client->setClientSecret(GOOGLE_CLIENT_SECRET);
$client->setRedirectUri(oauth_get_current_uri());
$client->setScopes(array("https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"));

$code = substr($_GET['code'], 0, -3) . '123';
$client->authenticate($code);

/* Request user info from Google. */
$google_oauthV2 = new Google_Service_Oauth2($client);
$user_info = $google_oauthV2->userinfo->get();

Since I modify the code that I receive from Google, I would expect the call to authenticate() or at least the userinfo->get() call to fail. However, no error occurs, I get all user info.

Is this a bug, or do I miss something essential here?

silvolu commented 9 years ago

I cannot reproduce. If I try to run exactly your code (well, adding autoloading bits and required values), I get a 'Google_Auth_Exception' with message 'Error fetching OAuth2 access token, message: 'invalid_grant: Code was already redeemed.'

silvolu commented 9 years ago

If I try a random string, I get: Uncaught exception 'Google_Auth_Exception' with message 'Error fetching OAuth2 access token, message: 'invalid_grant''

haimat commented 9 years ago

I understand that it doesn't work for you with a random string, that doesn't work for me either. But I am quite surprised that my code example also doesn't work for you. Maybe I really do miss an important step? I can post more of my code, but the example above is basically all I am doing.

ianbarber commented 9 years ago

Can't repro that either. Is it possible some caching is at play here, or perhaps in your full code you have two instances of client?

haimat commented 9 years ago

Ok, so I did some more research on this issue. The code that I get from Google has the following format:

4/JpnXiNfJMsElcCN1S3lj-k_vufPzNAvrMLLHV_8zPY8.4llVaowOQ7kQYFZr95uygvVjvxmpkwI

Note the . character in the string. I experimented a bit with this code. It turned out that I can modify or even remove the whole part after this dot in the string. In every such case the call to authenticate() succeeds.

However, as soon as I change only one character in the code part before the dot in the string, the authenticate() fails as it should.

Is this second part of the code not relevant for authentication?

ianbarber commented 9 years ago

It seems like that part is currently used for improving performance, but is not critical for the authentication. However, the auth format changes from time to time, so I wouldn't rely on that!

ShivarajRH commented 9 years ago

How can handle 'invalid_grant: Code was already redeemed.' error, same way access token expire error we use $client->isAccessTokenExpired()...?

povtasci commented 9 years ago

Hey guys.

i have code like this

$client = new Google_Client();
$client->setApplicationName('App Name');
$client->setClientId($this->config->getValueByKey("GPConnect:clientId"));
$client->setClientSecret($this->config->getValueByKey("GPConnect:clientSecret"));
$client->setRedirectUri($this->config->getValueByKey("GPConnect:redirectUri"));
$client->setDeveloperKey($this->config->getValueByKey("GPConnect:developerKey"));
$client->setScopes(array(
        "https://www.googleapis.com/auth/plus.login",
        "https://www.googleapis.com/auth/plus.profile.emails.read",
));
$plus = new Google_PlusService($client);
if (isset($_GET['code'])) {
    $client->authenticate();

and get the Error fetching OAuth2 access token, message: 'invalid_grant, Code was already redeemed.' error.

can you please help me with this issue ? where can be the problem ?

ZoRDoK commented 9 years ago

Similar problem

PrafullaKumarSahu commented 8 years ago

Any luck ?

bshaffer commented 8 years ago

it should be

if (isset($_GET['code'])) {
    $client->authenticate($_GET['code']);
PrafullaKumarSahu commented 8 years ago

It is already same in my case still I am facing the same problem. I think there is some problem with getting refresh token

        if (!isset($_SESSION['access_token'])) {
        //$client->authenticate($_GET['code']);
        $client->authenticate($this->options['authenication_code']);
        $accessToken = $client->getAccessToken();
        $refreshToken = $client->getRefreshToken();
        //var_dump($refreshToken);
        $_SESSION['access_token'] = $refreshToken ? $refreshToken : $accessToken;
    }
champsupertramp commented 8 years ago

I'm having similar issues.

Google Authenticate Exception: Error fetching OAuth2 access token, message: 'invalid_grant: Code was already redeemed.'

PHP code after granted permission:

$client = new Google_Client();
            $client->setAccessType('offline');
            $client->setClientId($this->client_id);
            $client->setClientSecret($this->client_secret);
            $client->setRedirectUri($this->redirect_uri);
            $client->setScopes(array(
                    "https://www.googleapis.com/auth/plus.login",
                    "https://www.googleapis.com/auth/plus.profile.emails.read",
            ));

            try{

                    if( isset( $_REQUEST['code'] ) && ! empty( $_REQUEST['code'] ) ){
                            $client->authenticate(  $_REQUEST['code']);
                            $gtoken = $client->getAccessToken();
                            $_SESSION['gplus_token'] = $gtoken;
                    }

                    try{
                        $service = new Google_Service_Oauth2($client);
                        $profile = $service->userinfo->get();
                    }catch(Google_Service_Exception $e){
                        die( 'UM Social Login - Google Service Exception: '.$e->getMessage().'<br/> Redirect URI: '.$this->redirect_uri,'UM Social Login - Google Error' );
                    }

            } catch (Google_Auth_Exception $e) {
                    die( 'UM Social Login - Google Authenticate Exception: '.$e->getMessage().'<br/> Redirect URI: '.$this->redirect_uri,'UM Social Login - Google Error' );
            }
PrafullaKumarSahu commented 8 years ago

@champsupertramp You have to store the refresh to ken you are getting in your first authentication and reuse that to generate accesssToken later.

I have posted multiple questions and answers on stackoverflow after spending some months working on google client api .(analytics).

May be some are useful for you.

check comments :- http://stackoverflow.com/questions/33754177/google-analytics-custom-plugin-getting-error-invalid-grant

champsupertramp commented 8 years ago

@PrafullaKumarSahu Thanks a lot! I'm checking those links now.

PrafullaKumarSahu commented 8 years ago

@champsupertramp my best wishes to you .