php - secret - oauth2 web application




Wie kann ein Token mit dem Google API-Client aktualisiert werden? (10)

Also habe ich endlich herausgefunden, wie das geht. Die Grundidee ist, dass Sie das Token haben, das Sie erhalten, wenn Sie zum ersten Mal nach einer Authentifizierung fragen. Dieses erste Token hat ein Aktualisierungstoken. Das erste ursprüngliche Token läuft nach einer Stunde ab. Nach einer Stunde müssen Sie das Aktualisierungstoken des ersten Tokens verwenden, um ein neues verwendbares Token zu erhalten. Sie verwenden $client->refreshToken($refreshToken) , um ein neues Token abzurufen. Ich werde das "Temp Token" nennen. Sie müssen dieses temporäre Token ebenfalls speichern, da es nach einer Stunde ebenfalls abläuft und nicht mit einem Aktualisierungs-Token verknüpft ist. Um ein neues temporäres Token zu erhalten, müssen Sie die Methode verwenden, die Sie zuvor verwendet haben, und die ersten Token-Token verwenden. Ich habe unten einen Code angehängt, der hässlich ist, aber ich bin neu in diesem ...

//pull token from database
$tokenquery="SELECT * FROM token WHERE type='original'";
$tokenresult = mysqli_query($cxn,$tokenquery);
if($tokenresult!=0)
{
    $tokenrow=mysqli_fetch_array($tokenresult);
    extract($tokenrow);
}
$time_created = json_decode($token)->created;
$t=time();
$timediff=$t-$time_created;
echo $timediff."<br>";
$refreshToken= json_decode($token)->refresh_token;


//start google client note:
$client = new Google_Client();
$client->setApplicationName('');
$client->setScopes(array());
$client->setClientId('');
$client->setClientSecret('');
$client->setRedirectUri('');
$client->setAccessType('offline');
$client->setDeveloperKey('');

//resets token if expired
if(($timediff>3600)&&($token!=''))
{
    echo $refreshToken."</br>";
    $refreshquery="SELECT * FROM token WHERE type='refresh'";
    $refreshresult = mysqli_query($cxn,$refreshquery);
    //if a refresh token is in there...
    if($refreshresult!=0)
    {
        $refreshrow=mysqli_fetch_array($refreshresult);
        extract($refreshrow);
        $refresh_created = json_decode($token)->created;
        $refreshtimediff=$t-$refresh_created;
        echo "Refresh Time Diff: ".$refreshtimediff."</br>";
        //if refresh token is expired
        if($refreshtimediff>3600)
        {
            $client->refreshToken($refreshToken);
        $newtoken=$client->getAccessToken();
        echo $newtoken."</br>";
        $tokenupdate="UPDATE token SET token='$newtoken' WHERE type='refresh'";
        mysqli_query($cxn,$tokenupdate);
        $token=$newtoken;
        echo "refreshed again";
        }
        //if the refresh token hasn't expired, set token as the refresh token
        else
        {
        $client->setAccessToken($token);
           echo "use refreshed token but not time yet";
        }
    }
    //if a refresh token isn't in there...
    else
    {
        $client->refreshToken($refreshToken);
        $newtoken=$client->getAccessToken();
        echo $newtoken."</br>";
        $tokenupdate="INSERT INTO token (type,token) VALUES ('refresh','$newtoken')";
        mysqli_query($cxn,$tokenupdate);
        $token=$newtoken;
        echo "refreshed for first time";
    }      
}

//if token is still good.
if(($timediff<3600)&&($token!=''))
{
    $client->setAccessToken($token);
}

$service = new Google_DfareportingService($client);

Ich habe mit der Google Analytics-API (V3) herumgespielt und bin auf einige Fehler gestoßen. Erstens ist alles korrekt eingerichtet und hat mit meinem Testkonto funktioniert. Aber wenn ich Daten von einer anderen Profil-ID (dasselbe Google Accont / GA-Konto) abrufen möchte, erhalte ich einen Fehler 403. Das Merkwürdige ist, dass Daten von einigen GA-Konten Daten zurückgeben, während andere diesen Fehler generieren.

Ich habe das Token zurückgenommen und erneut authentifiziert, und jetzt scheint es, als könnte ich Daten von allen meinen Konten abrufen. Problem gelöst? Nicht. Da der Zugriffsschlüssel abläuft, werde ich wieder auf dasselbe Problem stoßen.

Wenn ich die Dinge richtig verstanden habe, könnte man mit dem resfreshToken einen neuen AuthenticationTooken bekommen.

Das Problem ist, wenn ich renne:

$client->refreshToken(refresh_token_key) 

Der folgende Fehler wird zurückgegeben:

Error refreshing the OAuth2 token, message: '{ "error" : "invalid_grant" }'

Ich habe den Code hinter der refreshToken-Methode überprüft und die Anfrage zurück zur Datei "apiOAuth2.php" verfolgt. Alle Parameter werden korrekt gesendet. Der Grant_Type ist in der Methode fest auf "Refresh_Token" programmiert, so dass es mir schwer fällt zu verstehen, was falsch ist. Das Parameter-Array sieht so aus:

Array ( [client_id] => *******-uqgau8uo1l96bd09eurdub26c9ftr2io.apps.googleusercontent.com [client_secret] => ******** [refresh_token] => 1\/lov250YQTMCC9LRQbE6yMv-FiX_Offo79UXimV8kvwY [grant_type] => refresh_token )

Das Verfahren ist wie folgt.

$client = new apiClient();
$client->setClientId($config['oauth2_client_id']);
$client->setClientSecret($config['oauth2_client_secret']);
$client->setRedirectUri($config['oauth2_redirect_uri']);
$client->setScopes('https://www.googleapis.com/auth/analytics.readonly');
$client->setState('offline');

$client->setAccessToken($config['token']); // The access JSON object.

$client->refreshToken($config['refreshToken']); // Will return error here

Ist das ein Fehler oder habe ich etwas völlig falsch verstanden?


Das Problem liegt im Aktualisierungstoken:

[refresh_token] => 1\/lov250YQTMCC9LRQbE6yMv-FiX_Offo79UXimV8kvwY

Wenn eine Zeichenfolge mit einem '/' json encoded , wird es mit einem '\' ausgeblendet, daher müssen Sie es entfernen.

Das Aktualisierungs-Token sollte in Ihrem Fall sein:

1/lov250YQTMCC9LRQbE6yMv-FiX_Offo79UXimV8kvwY

Was ich angenommen habe, ist, dass Sie die JSON-Zeichenfolge, die Google zurückgeschickt hat, ausgedruckt und das Token in Ihren Code eingefügt haben, denn wenn Sie es json_decode , wird es das '\' für Sie korrekt entfernen!


Der Zugriffstyp sollte auf offline . state ist eine Variable, die Sie für Ihre eigene Verwendung festlegen, nicht die Verwendung der API.

Stellen Sie sicher, dass Sie über die neueste Version der Clientbibliothek verfügen, und fügen Sie Folgendes hinzu:

$client->setAccessType('offline');

Siehe Erstellen der URL für eine Erläuterung der Parameter.



Hier ist der Code, den ich in meinem Projekt verwende und es funktioniert gut:

public function getClient(){
    $client = new Google_Client();
    $client->setApplicationName(APPNAME);       // app name
    $client->setClientId(CLIENTID);             // client id
    $client->setClientSecret(CLIENTSECRET);     // client secret 
    $client->setRedirectUri(REDIRECT_URI);      // redirect uri
    $client->setApprovalPrompt('auto');

    $client->setAccessType('offline');         // generates refresh token

    $token = $_COOKIE['ACCESSTOKEN'];          // fetch from cookie

    // if token is present in cookie
    if($token){
        // use the same token
        $client->setAccessToken($token);
    }

    // this line gets the new token if the cookie token was not present
    // otherwise, the same cookie token
    $token = $client->getAccessToken();

    if($client->isAccessTokenExpired()){  // if token expired
        $refreshToken = json_decode($token)->refresh_token;

        // refresh the token
        $client->refreshToken($refreshToken);
    }

    return $client;
}

Hinweis: Die Google Analytics-API 3.0 aktualisiert das Zugriffstoken automatisch, wenn Sie ein Aktualisierungs-Token haben, wenn es abläuft, sodass Ihr Skript nie refreshToken benötigt.

(Siehe die Sign Funktion in auth/apiOAuth2.php )


Ich habe das gleiche Problem mit Google / Google-API-Client 2.0.0-RC7 und nach der Suche nach 1 Stunden, löste ich dieses Problem mit json_encode wie folgt :

    if ($client->isAccessTokenExpired()) {
        $newToken = json_decode(json_encode($client->getAccessToken()));
        $client->refreshToken($newToken->refresh_token);
        file_put_contents(storage_path('app/client_id.txt'), json_encode($client->getAccessToken()));
    }

Laut Authentifizierung bei Google: OAuth2 gibt immer 'invalid_grant' zurück

"Sie sollten das Zugriffstoken, das Sie nach der ersten erfolgreichen Authentifizierung erhalten haben, erneut verwenden. Sie erhalten einen invalid_grant-Fehler, wenn Ihr vorheriges Token noch nicht abgelaufen ist. Speichern Sie es irgendwo, damit Sie es wiederverwenden können."

ich hoffe es hilft


Verwenden Sie das folgende Code-Snippet, um Ihr Aktualisierungstoken zu erhalten

    <?php

    require_once 'src/apiClient.php';
    require_once 'src/contrib/apiTasksService.php';

    $client = new apiClient();
    $client->setAccessType('offline');
    $tasksService = new apiTasksService($client);

    $auth = $client->authenticate();
    $token = $client->getAccessToken();
    // the refresh token
    $refresh_token = $token['refresh_token'];
    ?>

Die Antwort, die von @ uri-weg gepostet wurde, hat für mich funktioniert, aber da ich seine Erklärungen nicht sehr klar fand, lass es mich ein wenig umschreiben.

Während der ersten Zugriffsberechtigungssequenz müssen Sie beim Rückruf an dem Punkt, an dem Sie einen Authentifizierungscode erhalten , das Zugriffstoken und das Aktualisierungstoken speichern .

Der Grund dafür ist, dass Google API Ihnen nur dann ein Zugriffstoken mit einem Aktualisierungstoken sendet, wenn Sie nach Zugriffsberechtigungen gefragt werden. Die nächsten Zugriffstoken werden ohne Aktualisierungstoken gesendet (es sei denn, Sie verwenden die Option approval_prompt=force ).

Das Aktualisierungstoken, das Sie zum ersten Mal erhalten haben, bleibt gültig, bis der Benutzer die Zugriffsberechtigung entzieht.

Im vereinfachten PHP wäre ein Beispiel für die Callback-Sequenz:

// init client
// ...

$authCode = $_GET['code'];
$accessToken = $client->authenticate($authCode);
// $accessToken needs to be serialized as json
$this->saveAccessToken(json_encode($accessToken));
$this->saveRefreshToken($accessToken['refresh_token']);

Und später, in vereinfachten PHP, wäre die Verbindungssequenz:

// init client
// ...

$accessToken = $this->loadAccessToken();
// setAccessToken() expects json
$client->setAccessToken($accessToken);

if ($client->isAccessTokenExpired()) {
    // reuse the same refresh token
    $client->refreshToken($this->loadRefreshToken());
    // save the new access token (which comes without any refresh token)
    $this->saveAccessToken($client->getAccessToken());
}




google-analytics-api