在 Laravel 5 中使用 Guzzle 和 Socialite 向 Google API 发出请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29342470/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 11:15:18  来源:igfitidea点击:

Making requests to Google API using Guzzle and Socialite in Laravel 5

laravelgoogle-apigoogle-oauthguzzlelaravel-socialite

提问by ferenan

I'm building a web app that has to interact with Google Contacts API and retrieve the Contact List of the authenticated user, but I'm getting

我正在构建一个必须与 Google Contacts API 交互并检索经过身份验证的用户的联系人列表的网络应用程序,但我得到了

ClientException in RequestException.php line 89:
Client error response [url] https://www.google.com/m8/feeds/contacts/[email protected]/full?prettyPrint=false [status code] 403 [reason phrase] Forbidden

Here's my AuthenticateUser.php where I have included the getContactList function, I'm trying to make the Guzzle Request to the Google Server and managed to send the correct access token by storing it in a session variable, but I'm still getting a forbidden response :

这是我的 AuthenticateUser.php,我在其中包含了 getContactList 函数,我正在尝试向 Google 服务器发出 Guzzle 请求并设法通过将其存储在会话变量中来发送正确的访问令牌,但我仍然收到禁止回复 :

<?php
namespace App;
use Laravel\Socialite\Contracts\Factory as Socialite;
use App\Repositories\UserRepository;
use Illuminate\Contracts\Auth\Guard;


class AuthenticateUser {

    /**
     * @var UserRepository
     */
    private $users;
    /**
     * @var Socialite
     */
    private $socialite;
    /**
     * @var Guard
     */
    private $guard;

    private $token;

    public function __construct(UserRepository $users, Socialite $socialite, Guard $guard)
    {

        $this->users = $users;
        $this->socialite = $socialite;
        $this->guard = $guard;
    }


    /**
     * @param $hasCode
     * @param AuthenticateUserListener $listener
     * @return mixed
     */
    public function execute($hasCode, AuthenticateUserListener $listener)
    {

        if ( ! $hasCode ) return $this->getAuthorizationFirst();

        $var = $this->getGoogleUser();

        $user = $this->users->findByUsernameOrCreate($var);

        \Session::put('token', $var->token );

        \Auth::login($user, true);

        return $listener->userHasLoggedIn($user);

    }

    public function logout()
    {

        \Auth::logout();

        return redirect('/');


    }

    private function getAuthorizationFirst()
    {

        return \Socialize::with('google')->redirect();

    }

    private function getGoogleUser()
    {

        return \Socialize::with('google')->user();
    }

    public function getContactList()
    {

        $client = new \GuzzleHttp\Client();

        $email = \Auth::user()->email;

        $token = \Session::get('token');

        $json = $client->get('https://www.google.com/m8/feeds/contacts/'. $email . '/full', [
            'query' => [
                'prettyPrint' => 'false',
            ],
            'headers' => [
                'Accept' => 'application/json',
                'Authorization' => 'Bearer ' . $token ,
            ],
        ]);

        dd($json);

        return $json;

    }
}

Here's my AuthController.php

这是我的 AuthController.php

<?php namespace App\Http\Controllers;

use App\AuthenticateUser;
use App\AuthenticateUserListener;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Laravel\Socialite\Two\GoogleProvider as Google;

use Illuminate\Http\Request;

class AuthController extends Controller implements AuthenticateUserListener
{

    public function login(AuthenticateUser $authenticateUser, Request $request){

       return $authenticateUser->execute($request->has('code'), $this);
    }

    public function userHasLoggedIn($user)
    {

        return redirect('/');
    }

    public function logout(AuthenticateUser $authenticateUser){


        return $authenticateUser->logout();

    }

    public function getContactList(AuthenticateUser $authenticateUser)
    {
        $response = $authenticateUser->getContactList();

        dd($response);
    }
}

Here's my MainController.php

这是我的 MainController.php

<?php namespace App\Http\Controllers;

use App\Http\Requests;
use App\Http\Controllers\Controller;

use Illuminate\Http\Request;

class MainController extends Controller {


    public function index()
    {
        if (\Auth::check()) return redirect('google_welcome');
        return redirect('google_login');
    }

    public function first()
    {
        return view('google_login');
    }

    public function back()
    {
        $user = \Auth::user();
        return view('google_welcomeback')->with('user', $user);
    }

}

I'm fairly new to the PHP and Laravel universe, what's with trying to immediately use Google APIs and packages such as socialite which is using oAuth 2. I have really struggled to make the most out of my limited knowledge and haven't really found much documentation online, and the problem is my employer hinted that I either have to complete this as fastly as possible or he's gonna show me the way out...

我对 PHP 和 Laravel 领域相当陌生,尝试立即使用 Google API 和软件包(例如使用 oAuth 2 的 socialite)有何意义。我真的很难充分利用我有限的知识,但还没有真正找到网上有很多文档,问题是我的雇主暗示我要么必须尽快完成,否则他会告诉我出路......

采纳答案by ferenan

I have managed to get by and finally got past that error, changing my getContactList function to the following and adding the proper scope :

我设法克服并最终克服了该错误,将我的 getContactList 函数更改为以下内容并添加适当的范围:

 public function getContactList()
    {
        $config = [
            'client_id' => env('CLIENT_ID', ''),
            'client-secret' => env('CLIENT_SECRET', ''),
        ];

        $client = new \GuzzleHttp\Client($config);

        $email = \Auth::user()->email;

        $token = \Session::get('token');

        $json = $client->get('https://www.google.com/m8/feeds/contacts/default/full/',  [

            'headers' => [

                'Authorization' => 'Bearer ' . $token,

            ],
        ]);

        dd($json);

        return $json;

回答by nostah

I had the very same problem today. Debugging Socialite I've found out that there's a problem with get authorization token call to google.

我今天遇到了同样的问题。调试 Socialite 我发现获取授权令牌调用 google 存在问题。

In the end it turned out to be just client secret copy-pasted wrongly to configuration.

最后结果证明只是客户端机密被错误地复制粘贴到配置中。

To discover real source of problem, you can try following command:

要发现问题的真正根源,您可以尝试以下命令:

curl -v -d grant_type=authorization_code -d client_id="<YOUR_ID_HERE>" -d client_secret="<YOUR_SECRET_HERE>" -d code="<CODE_HERE>" -d redirect_uri="<YOUR_CALLBACK_URI_HERE>" https://accounts.google.com/o/oauth2/token

Client ids/secrets/uris you already have and code can be obtained with debugger or adding some debug print in ./vendor/laravel/socialite/src/Two/GoogleProvider.php - for example in getAccessToken($code) method.

您已经拥有的客户端 ids/secrets/uris 和代码可以通过调试器获取或在 ./vendor/laravel/socialite/src/Two/GoogleProvider.php 中添加一些调试打印 - 例如在 getAccessToken($code) 方法中。

For me it resulted in real answer:

对我来说,它得到了真正的答案:

{
  "error" : "invalid_client",
  "error_description" : "The OAuth client was not found."
}

Once you fix this there's another caveat that's not documented - Socialite needs your Google app to have Google+ API enabled. This can be done at: https://console.developers.google.com

一旦你解决了这个问题,还有一个没有记录在案的警告 - Socialite 需要你的 Google 应用程序启用 Google+ API。这可以在:https: //console.developers.google.com上完成