【问题标题】:laravel - Google Analytics API Authenticationlaravel - 谷歌分析 API 身份验证
【发布时间】:2016-11-11 14:57:06
【问题描述】:

我正在尝试创建一个带有简单仪表板的网络应用程序,其中包含使用 Google 登录的帐户的分析数据。我正在使用 Laravel 和 Socialite 包,我目前可以用谷歌登录用户。我有我的开发者客户端密钥和客户端密钥。我为 Analytics 只读和离线访问设置了范围,并将客户姓名、电子邮件、Google ID、访问令牌和刷新令牌存储在我的数据库中。我可以毫无问题地登录用户。

我现在要做的是访问 Google Analytics(分析)帐户当前拥有的配置文件。我遵循了 Analytics API 文档示例,但无法使其正常工作。由于我正在存储访问令牌和刷新令牌,我认为我应该能够验证当前用户并获取他们的分析数据,但我无法从客户端和分析库中找到任何简单的方法。我需要离线访问他们的 Analytics 数据,这就是为什么我认为我应该能够使用访问令牌和刷新令牌授权我的请求,但我没有从用户登录过程中获得任何 Analytics 特定数据。我现在完全迷失了,如何授权我对 Anayltics API 的请求?我已经使用 AdWords API 超过 8 个月了,AdWords API 文档中的一切都一清二楚,但我无法使用 Analytics API。

这些是我的用户登录方法:

public function redirectToProvider()
{
    $parameters = ['access_type' => 'offline'];
    return Socialite::driver('google')
        ->scopes(['https://www.googleapis.com/auth/analytics.readonly'])
        ->with($parameters)
        ->redirect();
}

/**
 * Obtain the user information from Google.
 *
 * @return Response
 */
public function handleProviderCallback()
{
    $outsiderLogin = Socialite::driver('google')->stateless()->user();


    $user = User::where('googleID', $outsiderLogin->id)->first();

    // Register the user if there is no user with that id.
    if (!$user) {
        $user = new User;
        $user->name         = $outsiderLogin->name;
        $user->googleID     = $outsiderLogin->id;
        $user->email        = $outsiderLogin->email;
        $user->token        = $outsiderLogin->token;
        $user->refreshToken = $outsiderLogin->refreshToken;
        $user->save();
    }
    // Log the user in.
    Auth::login($user);

    return redirect('/home');
}

非常感谢。

【问题讨论】:

    标签: php api laravel google-analytics laravel-socialite


    【解决方案1】:

    我现在已经找到了解决方案。起初,我认为我需要从谷歌返回身份验证 URL 的代码,当我检查 Socialite 包时,我在 \vendor\laravel\socialite\src\Two\AbstractProvider.php 中找到了一个受保护的方法 getCode(),它从 URL 返回代码。我编辑了包的源文件并将方法类型从protected 更改为public,这样就可以在类之外使用该方法,这使我可以从 URL 访问代码,然后存储它在 DB 中以获取进一步的身份验证要求。但是这个设置存在问题,首先,我应该找到一种方法来保留该包而不进行任何更新,因为任何更新都会回滚我对源文件所做的更改。我面临的第二个问题是我存储令牌的方式。默认情况下,Google 客户端 API 返回一个包含字段 access_token、refresh_token、expires_in、id 和 created 的数组,并使用这些字段验证对分析服务器的请求。在我的场景中,没有从基本社交名流登录过程返回的标准数组。有access_token、refresh_token 和expires 变量,我也将它们全部存储在我的数据库中。这导致了谷歌库的问题,它要求一个结构化数组,我什至没有变量expires_in 和created,这就是为什么我设置一个假数组告诉谷歌在每个请求时刷新令牌,而这个也不是一个好习惯。

    最后,我无法理解如何在线使用任何包,我自己编写了简单的身份验证,我不知道它是否有任何漏洞,但它对我有用,它也可能对那些需要的人有用它。

    这是我的路线:

    Route::get('auth/google', [
                'as' => 'googleLogin',   
                'uses' => 'Auth\AuthController@redirectToProvider'
    ]);
    Route::get('auth/google/callback', [
                'as' => 'googleLoginCallback',   
                'uses' => 'Auth\AuthController@handleProviderCallback'
    ]);
    

    这些是AuthController 方法:

    /**
     * Redirect the user to the Google authentication 
     */
    public function redirectToProvider()
    {
        // Create the client object and set the authorization configuration from JSON file.
        $client = new Google_Client();
        $client->setAuthConfig('/home/vagrant/Analytics/client_secret.json');
        $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/auth/google/callback');
        $client->addScope(Google_Service_Analytics::ANALYTICS_READONLY);
        $client->addScope("email");
        $client->addScope("profile");
        $client->setAccessType("offline");
    
        $auth_url = $client->createAuthUrl();
        return redirect($auth_url);
    
    }
    
    /**
     * Obtain the user information from Google.
     *
     * @return redirect to the app.
     */
    public function handleProviderCallback()
    {
        // Handle authorization flow from the server.
        if (! isset($_GET['code'])) {
            return redirect('auth/google');
        } else {
    
            // Authenticate the client, and get required informations.
            $client = new Google_Client();
            $client->setAuthConfig('/home/vagrant/Analytics/client_secret.json');
            $client->authenticate($_GET['code']);
    
            // Store the tokens in the session.
            Session::put('token', $client->getAccessToken());
    
            $service = new Google_Service_Oauth2($client);
            $userInfo = $service->userinfo->get();
    
            $user = User::where('googleID', $userInfo->id)->first();
    
            // If no match, register the user.
            if(!$user) {
                $user = new User;
                $user->name = $userInfo->name;
                $user->googleID = $userInfo->id;
                $user->email = $userInfo->email;
                $user->refreshToken = $client->getRefreshToken();
                $user->code = $_GET['code'];
                $user->save();
            }
    
            Auth::login($user);
            return redirect('/home');
        }
    
    }
    

    我已经将我从 Google API 控制台下载的client_secret.json 文件放到了指定的文件夹中,这对你来说可能会有所不同。我还修改了迁移文件以匹配所需的段。完成这些步骤后,我可以将该用户视为使用基本 Laravel 身份验证注册的简单用户。

    现在我可以像这样查询用户的 Google Analytics(分析)帐户中的帐户:

    /**
     * @var $client to be authorized by Google.
     */
    private $client;
    
    /**
     * @var $analytics Analytics object to be used.
     */
    private $analytics;
    
    public function __construct()
    {
        $this->client = $this->AuthenticateCurrentClient();
        $this->analytics = new Google_Service_Analytics($this->client);
    }
    
    private function AuthenticateCurrentClient(){
        $user = Auth::user();
        $token = Session::get('token');
    
        // Authenticate the client.
        $client = new Google_Client();
        $client->setAccessToken($token);
        $client->authenticate($user->code);
        return $client;
    }
    
    public function GetAccounts(){
    
        try {
            $accountsObject = $this->analytics->management_accounts->listManagementAccounts();
            $accounts = $accountsObject->getItems();
    
            return $accounts;
    
        } catch (apiServiceException $e) {
            print 'There was an Analytics API service error '
                . $e->getCode() . ':' . $e->getMessage();
    
        } catch (apiException $e) {
            print 'There was a general API error '
                . $e->getCode() . ':' . $e->getMessage();
        }
    
    }
    

    Stack Overflow 帮助了我数千次,我希望这可以帮助某人让事情正常进行。

    【讨论】:

      【解决方案2】:

      你不会真的通过 Laravel 附带的 Socialite 包找到你正在寻找的东西(它更多地用于登录,仅此而已)。

      您可以在此处找到许多 Google Analytic 软件包(以及许多其他 Laravel 捆绑包),它们应该可以帮助您进行 API 调用:

      http://packalyst.com/s/google%20analytics

      更具体地说,这个包:https://github.com/spatie/laravel-analytics

      那个,或者运行你自己的 Guzzle 和 cURL 脚本。当我需要一些快速的东西而不构建完整的 API 时,我会使用 Guzzle。

      但是,这里有一篇关于使用社交名流访问 GA 数据的有趣帖子。但是你的能力很有限。如果您要创建用户驱动的仪表板,我会选择单独的包。

      https://laracasts.com/discuss/channels/tips/how-i-made-google-analytics-work-with-socialite

      【讨论】:

      • 首先,非常感谢。我见过大部分这些包,但这些包似乎需要一个类似于ga-123456 的 Google Analytics View ID,我认为这不是一个好的用户体验。作为用户,我希望该网页在成功验证后无需额外努力即可获取所有数据。这就是事情变得复杂的地方,我需要从 GA 获取数据,但是没有视图 ID 或者授权过程没有任何内容,这就是我卡住的地方。我有访问令牌,但这些软件包都不能使用该访问令牌?
      • 社交名流不是你的答案。所以你需要看看不同的选择。我将这个包用于我所有的 Google API 服务。但是搜索 Packalyst 并找到您最喜欢的一个。 github.com/pulkitjalan/google-apiclient
      • 非常感谢。我现在已经找到了与 Socialite 合作的方式,并且由于我有该项目的最后期限,我想我会像现在一样使用它,直到 MVP。我想我会迁移到你使用的包,它看起来非常简单易用。谢谢,你帮我弄明白了。
      【解决方案3】:

      我也在尝试做同样的事情。到目前为止,我已经使用 oAuth 2.0 和 Socialite 包进行了用户身份验证。我需要从 GA 获取网站列表。我完全被困在那里。如果您能指导我如何继续前进,那就太好了..

      【讨论】:

      • Socialite 不是此类身份验证或 API 通信过程的解决方案。您需要更新 Socialite 包的源代码,这没有意义,因为您需要在每次更新时重做更改。 Socialite 仅用于简单的登录工作,您只需要用户的信息。你在这里检查我的答案吗?我已经提供了获取帐户的代码。我不确定是否有直接获取网站的方法,但您可以获取 GA 帐户,然后获取属性,其中包含每个属性的 URL。
      • 哪个代码?所有的代码都在这里,代码的其他部分是与业务相关的部分。您可以在帖子中使用这些方法登录并获取帐户报告。如果你愿意,我可以在有时间的时候创建一个要点或其他东西。
      • 是的,请这样做。我也想知道 guzzle requests
      • 如果您可以发布 Google_Client()、Google_Service_Analytics 和 Google_Service_Oauth2(),将会有很大帮助
      • 这些来自谷歌客户端库,我没有为这些类或方法写任何东西。我检查了我的文件,上面的代码实际上没有任何其他内容。您有什么特别需要我可以帮助的?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-08
      • 1970-01-01
      • 2012-07-23
      • 2020-09-26
      • 2010-10-16
      • 1970-01-01
      • 2022-01-27
      相关资源
      最近更新 更多