为什么我要继续捕获Google_Auth_Exception for invalid_grant? [英] Why do I keep catching a Google_Auth_Exception for invalid_grant?

查看:104
本文介绍了为什么我要继续捕获Google_Auth_Exception for invalid_grant?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建访问Google AnalyticsAPI并提取数据的网络应用。但是,我在OAuth 2.0授权方面遇到了一些问题。



它允许成功初始访问,但它很快将我踢出去并抛出一个Google_Auth_Exception,其中包含消息'Error fetching当我点击刷新页面的提交按钮时,OAuth2访问令牌,消息:'invalid_grant''。

据我了解OAuth 2.0,有4个步骤进行身份验证:


  1. 从Google开发者控制台获取OAuth 2.0凭据

  2. 从Google授权服务器获取访问令牌

  3. 将访问令牌发送到Google Analytics API

  4. 根据我的理解,$ client-> setAccessToken()可以使用
  5. 刷新访问令牌(如果需要的话)

;自动刷新标记。



自从他们转到Github后,我似乎无法从Google获得任何文档,并且我大部分都遵循了他们的示例结构。 >

当第一个try块试图执行$ client-> authenticate($ _ GET ['code']);

我目前的解决方法是取消设置会话令牌,并让用户重新授权。然而,这是非常麻烦和侵入性的,因为任何与页面的交互都会要求重新授权。



任何帮助都将不胜感激!



以下是我的代码:

 <?php 

/ **********************
OAUTH 2.0授权
**************** ******* /

//所需的库
set_include_path(../ src /。PATH_SEPARATOR。get_include_path());
require_once'Google / Client.php';
require_once'Google / Service / Analytics.php';


//变量
$ client_id ='redacted';
$ client_secret ='redacted';
$ redirect_uri ='http://'.$_SERVER [HTTP_HOST]。$ _ SERVER ['PHP_SELF'];
$ dev_key ='redacted';

//创建Google客户端
$ client = new Google_Client();
$ client-> setApplicationName('App');

//设置客户端的API信息
$ client-> setClientId($ client_id);
$ client-> setClientSecret($ client_secret);
$ client-> setRedirectUri($ redirect_uri);
$ client-> setDeveloperKey($ dev_key);
$ client-> setScopes(array('https://www.googleapis.com/auth/analytics.readonly'));

//如果要求注销,撤销访问
if(isset($ _ REQUEST ['logout'])){
unset($ _ SESSION ['token'] );
}

//检查授权码是否在URL中
try {
if(isset($ _ GET ['code'])){
$ client-> authenticate($ _ GET ['code']); //授权工作
$ _SESSION ['access_token'] = $ client-> getAccessToken(); //获取有效访问令牌
$ redirect ='https://'。 $ _SERVER ['HTTP_HOST']。 $ _SERVER [ PHP_SELF]; //设置为会话存储
header('Location:'。filter_var($ redirect,FILTER_SANITIZE_URL)); //清理URL
}
}
//如果授权码现在无效
catch(Google_Auth_Exception $ e){
unset($ _ SESSION ['令牌']); //取消设置会话令牌
回显令牌现在无效,请重新验证。< br>;
}

//如果会话存储中存在访问令牌
if(isset($ _ SESSION ['access_token'])&& $ _SESSION ['access_token ']){
$ client-> setAccessToken($ _ SESSION ['access_token']); //设置客户端的访问令牌

//尝试创建一个分析对象
尝试{
$ analytics = new Google_Service_Analytics($ client);
echo'已成功创建Google Analytics客户端! <峰; br><峰; br>;
}
catch(Google_Auth_Exception $ e){
echo'需要授权!';
}
} else {
$ authUrl = $ client-> createAuthUrl(); //创建一个
回显< a class ='login'href ='$ authUrl'><按钮>授权Google Access< /按钮>< / a>; //打印按钮
}


解决方案

问题。我尝试两次授权相同的认证码,因此它返回了一个 invalid_grant 错误。



我的解决方案是重写大部分代码并修复OAuth2逻辑。



我已经创建了以下OAuth2身份验证流程的迷你教程:

 <?php 
session_start(); //创建会话

/ **************************
* Google客户端配置
*
*您可能想要考虑采用模块化方法
*并在单独的PHP文件中执行以下操作。
*************************** /

/ *所需的Google图书馆* /
require_once'Google / Client.php';
require_once'Google / Service / Analytics.php';

/ * API客户端信息* /
$ clientId ='YOUR-CLIENT-ID-HERE';
$ clientSecret ='YOUR-CLIENT-SECRET-HERE';
$ redirectUri ='http://www.example.com/';
$ devKey ='YOUR-DEVELOPER-KEY-HERE';

//创建一个Google客户端。
$ client = new Google_Client();
$ client-> setApplicationName('App'); //在这里设置您的应用程序名称

/ *使用您的API信息配置Google客户端* /

//设置客户端ID和秘密。
$ client-> setClientId($ clientId);
$ client-> setClientSecret($ clientSecret);

//在这里设置重定向网址 - 这应该与您提供的相符。
$ client-> setRedirectUri($ redirectUri);

//设置开发人员密钥和您的应用程序范围。
$ client-> setDeveloperKey($ devKey);
$ client-> setScopes(
array('https://www.googleapis.com/auth/analytics.readonly')
);

/ **************************
* OAuth2身份验证流程
*
*您可能需要考虑采用模块化方法
*并在单独的PHP文件中执行以下操作。
*************************** /

//使用配置的创建Google Analytics服务Google客户端。
$ analytics =新Google_Service_Analytics($ client);

//检查URL中是否有注销请求。
if(isset($ _ REQUEST ['logout'])){
//清除会话存储中的访问令牌。
unset($ _ SESSION ['access_token']);
}

//检查URL中是否有验证码。
//认证码附加到
之后的URL中//用户被成功从认证重定向。
if(isset($ _GET ['code'])){
//将验证码与Google客户端交换。
$ client-> authenticate($ _ GET ['code']);

//从Google客户端检索访问令牌。
//在这个例子中,我们将访问令牌存储在
//会话存储器中 - 您可能希望使用数据库。
$ _SESSION ['access_token'] = $ client-> getAccessToken();

//获取访问令牌后,您不再需要URL中的
//授权代码。将用户重定向到一个干净的URL。
header('Location:'.filter_var($ redirectUri,FILTER_SANITIZE_URL));
}

//如果会话存储中存在访问令牌,则可以使用
//来验证Google客户端的授权使用情况。
if(isset($ _ SESSION ['access_token'])&& $ _SESSION ['access_token']){
$ client-> setAccessToken($ _ SESSION ['access_token']);
}

//如果Google客户端没有经过身份验证的访问令牌,则
//让用户通过OAuth2身份验证流程。
if(!$ client-> getAccessToken()){
//获取OAuth2认证URL。
$ authUrl = $ client-> createAuthUrl();

/ *让用户访问URL并在此处进行身份验证* /

//在此处显示身份验证URL。
}

/ **************************
* OAuth2身份验证完成
*
*在这里插入您的API调用
*************************** /

希望这可以帮助未来的人坚持下去!


I am trying to build a web app that accesses Google Analytics API, and pull data. However, I have having some issues with the OAuth 2.0 authorization.

It allows for successful initial access, but it quickly kicks me out and throws a Google_Auth_Exception with message 'Error fetching OAuth2 access token, message: 'invalid_grant'' when I hit a submit button that refreshes the page.

As I understand OAuth 2.0, there are 4 steps to authentication:

  1. Obtain OAuth 2.0 credentials from Google Dev Console
  2. Obtain an access token from Google Authorization Server
  3. Send the access token to Google Analytics API
  4. Refresh the access token, if necessary

And as I understand it, $client->setAccessToken(); automatically refreshes the token.

I cannot seem to find any documentation from Google since they moved to Github, and I have followed their example structures for the most part.

The error is thrown from the first try block, when it tries to execute $client->authenticate($_GET['code']);

My current workaround is to unset the session token, and have the user re-authorize. However, this is really cumbersome and intrusive, as any interaction with the page will ask for re-authorization.

Any help would be greatly appreciated!

Here is my code:

<?php

    /**********************
    OAUTH 2.0 AUTHORIZATION
    ***********************/

    //required libraries
    set_include_path("../src/" . PATH_SEPARATOR . get_include_path());
    require_once 'Google/Client.php';
    require_once 'Google/Service/Analytics.php';


    //variables
    $client_id = 'redacted';
    $client_secret = 'redacted';
    $redirect_uri = 'http://'.$_SERVER["HTTP_HOST"].$_SERVER['PHP_SELF'];
    $dev_key = 'redacted';

    //create a Google client
    $client = new Google_Client();
    $client->setApplicationName('App');

    //sets client's API information
    $client->setClientId($client_id);
    $client->setClientSecret($client_secret);
    $client->setRedirectUri($redirect_uri);
    $client->setDeveloperKey($dev_key);
    $client->setScopes(array('https://www.googleapis.com/auth/analytics.readonly'));

    //if log out is requested, revoke the access
    if (isset($_REQUEST['logout'])) {
        unset($_SESSION['token']);
    }

    //check if authorization code is in the URL
    try{
        if (isset($_GET['code'])) {
    $client->authenticate($_GET['code']); //does authorization work
    $_SESSION['access_token'] = $client->getAccessToken(); //gets valid access token
    $redirect = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']; //set into session storage
    header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL)); //cleans up the URL
}
}
//if the authorization code is now invalid
catch (Google_Auth_Exception $e) {
    unset($_SESSION['token']); //unset the session token
    echo "Token now invalid, please revalidate. <br>";
}

//if there is an access token in the session storage
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
    $client->setAccessToken($_SESSION['access_token']); //set the client's access token

    //try creating an analytics object
    try {
        $analytics = new Google_Service_Analytics($client);
        echo 'Created Google Analytics Client successfully! <br><br>';
    }
    catch (Google_Auth_Exception $e) {
        echo 'Need authorization!';
    }
} else {
    $authUrl = $client->createAuthUrl(); //create one
    echo "<a class='login' href='$authUrl'><button>Authorize Google Access</button></a>"; //print button
}

解决方案

I resolved the issue. I was trying to authorize the same authentication code twice, and therefore it returned an invalid_grant error.

My solution was to rewrite much of the code and fix the OAuth2 logic.

I have created a mini-tutorial of the OAuth2 authentication flow below:

<?php
    session_start(); // Create a session

    /**************************
    * Google Client Configuration
    *
    * You may want to consider a modular approach,
    * and do the following in a separate PHP file.
    ***************************/

    /* Required Google libraries */
    require_once 'Google/Client.php';
    require_once 'Google/Service/Analytics.php';

    /* API client information */
    $clientId = 'YOUR-CLIENT-ID-HERE';
    $clientSecret = 'YOUR-CLIENT-SECRET-HERE';
    $redirectUri = 'http://www.example.com/';
    $devKey = 'YOUR-DEVELOPER-KEY-HERE';

    // Create a Google Client.
    $client = new Google_Client();
    $client->setApplicationName('App'); // Set your app name here

    /* Configure the Google Client with your API information */

    // Set Client ID and Secret.
    $client->setClientId($clientId);
    $client->setClientSecret($clientSecret);

    // Set Redirect URL here - this should match the one you supplied.
    $client->setRedirectUri($redirectUri);

    // Set Developer Key and your Application Scopes.
    $client->setDeveloperKey($devKey);
    $client->setScopes(
        array('https://www.googleapis.com/auth/analytics.readonly')
    );

    /**************************
    * OAuth2 Authentication Flow
    *
    * You may want to consider a modular approach,
    * and do the following in a separate PHP file.
    ***************************/

    // Create a Google Analytics Service using the configured Google Client.
    $analytics = new Google_Service_Analytics($client);

    // Check if there is a logout request in the URL.
    if (isset($_REQUEST['logout'])) {
        // Clear the access token from the session storage.
        unset($_SESSION['access_token']);
    }

    // Check if there is an authentication code in the URL.
    // The authentication code is appended to the URL after
    // the user is successfully redirected from authentication.
    if (isset($_GET['code'])) {
        // Exchange the authentication code with the Google Client.
        $client->authenticate($_GET['code']); 

        // Retrieve the access token from the Google Client.
        // In this example, we are storing the access token in
        // the session storage - you may want to use a database instead.
        $_SESSION['access_token'] = $client->getAccessToken(); 

        // Once the access token is retrieved, you no longer need the
        // authorization code in the URL. Redirect the user to a clean URL.
        header('Location: '.filter_var($redirectUri, FILTER_SANITIZE_URL));
    }

    // If an access token exists in the session storage, you may use it
    // to authenticate the Google Client for authorized usage.
    if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
        $client->setAccessToken($_SESSION['access_token']);
    }

    // If the Google Client does not have an authenticated access token,
    // have the user go through the OAuth2 authentication flow.
    if (!$client->getAccessToken()) {
        // Get the OAuth2 authentication URL.
        $authUrl = $client->createAuthUrl();

        /* Have the user access the URL and authenticate here */

        // Display the authentication URL here.
    }

    /**************************
    * OAuth2 Authentication Complete
    *
    * Insert your API calls here 
    ***************************/

Hope this helps someone stuck in the future!

这篇关于为什么我要继续捕获Google_Auth_Exception for invalid_grant?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆