首页 > 解决方案 > 验证 Google Client Auth 2.0 时如何修复 invalid_grant 错误

问题描述

您好,我正在尝试开始使用 Google API,我正在尝试使用我的应用程序发送电子邮件,但是当我 var_dump( $this->client->authenticate($code))时出现此错误

这是我的文件。

GmailAPI.php

<?php
namespace App\Helper;
final class GmailAPI
{
    private  $credentials= array (
        'client_id'=>"344731126834-9mh8qf95j5m9gl4vqqs7rig5t2ftdih3.apps.googleusercontent.com",
        'project_id'=>"checkin-262204",
        'auth_uri' =>"https://accounts.google.com/o/oauth2/auth",
        'token_uri'=>"https://oauth2.googleapis.com/token",
        'auth_provider_x509_cert_url'=>"https://www.googleapis.com/oauth2/v1/certs",
        'client_secret'=>"t-0feVVwO636qBHDCQYd2uka",
    );

    public $client;

    public function __construct() {
      $this->client = new \Google_Client();
      $this->client->setAuthConfigFile($this->credentials);
      $this->client->setAccessType("offline");
      $this->client->setIncludeGrantedScopes(true);
      $this->client->addScope(\Google_Service_Gmail::GMAIL_SEND);
   //   $this->client->setLoginHint('afashaisakiye@gmail.com');

    }

    /**
     * Returns an authorized API client.
     * @return Google_Client the authorized client object
     */
    public function getClientFromAccessToken($accessToken=NULL)
    {
        $this->client->setAccessToken($accessToken);

        if ($this->client->isAccessTokenExpired()) {
          return false;
        }

        return $this->client;
    }


    public function refreshToken()
    {
      if ($this->client->getRefreshToken()) {


        $this->client->fetchAccessTokenWithRefreshToken($this->client->getRefreshToken());
        $token=$this->client->getRefreshToken();
        return $token;
      }else{
        return false;
      }
    }

    public function getNewAccessToken($code){
      echo "<pre>";
      var_dump($this->client->authenticate($code));
      $this->client->setAccessToken($code);
      $accessToken = $this->client->getAccessToken();
      return $accessToken; 
    }

    public function createGoogleUrl()
    {
      $this->client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/test');
      $auth_url = $this->client->createAuthUrl();
      return $auth_url;
    }


    public function createMessage($email) {
        $message = new Google_Service_Gmail_Message();
        $email = strtr(base64_encode($email), array('+' => '-', '/' => '_'));
        $message->setRaw($email);
        return $message;
    }

    public function createDraft($service, $user, $message) {
        $draft = new \Google_Service_Gmail_Draft();
        $draft->setMessage($message);
        try {
          $draft = $service->users_drafts->create($user, $draft);
          print 'Draft ID: ' . $draft->getId();
        } catch (Exception $e) {
          print 'An error occurred: ' . $e->getMessage();
        }
        return $draft;
    }

    public function sendMessage($service, $userId, $message) {
        //sends an email message.
          try {
            $message = $service->users_messages->send($userId, $message);
            print 'Message with ID: ' . $message->getId() . ' sent.';
            return $message;
          } catch (Exception $e) {
            print 'An error occurred: ' . $e->getMessage();
          }
    }
}

测试控制器.php

<?php

namespace App\Controllers;

class TestController extends Controller
{   

    public function index($request, $response){

        $gmailAPI= new \App\Helper\GmailAPI();

        if($request->getParam('code')){
            $code=$request->getParam('code');
            $accesstoken=$gmailAPI->getNewAccessToken($code);

            var_dump($accesstoken);
            die();
            $client=$accesstoken;
        }else{

            $token=$this->container->db->get('gmailapi_accesstokens',[
                'access_token',
                'scope',
                'created',
                'expires_in',
                'token_type'
            ],[
                'user_id'=>0
            ]);

            $client=$gmailAPI->getClientFromAccessToken($token);

            if(!$client){
                $redirect_uri=$gmailAPI->createGoogleUrl();
                header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
                die();
            }

        }


        if($client){
            $service = new \Google_Service_Gmail($gmailAPI->client);
            $strSubject = 'Test mail using GMail API' . date('M d, Y h:i:s A');
            $strRawMessage = "From: Afasha Isakiye <afashaisakiye@gmail.com>\r\n";
            $strRawMessage .= "To: SUFCHAMPION <isakiyeafasha@gmail.com>\r\n";
            $strRawMessage .= 'Subject: =?utf-8?B?' . base64_encode($strSubject) . "?=\r\n";
            $strRawMessage .= "MIME-Version: 1.0\r\n";
            $strRawMessage .= "Content-Type: text/html; charset=utf-8\r\n";
            $strRawMessage .= 'Content-Transfer-Encoding: quoted-printable' . "\r\n\r\n";
            $strRawMessage .= "this <b>is a test message!\r\n";

            // The message needs to be encoded in Base64URL
            $mime = rtrim(strtr(base64_encode($strRawMessage), '+/', '-_'), '=');
            $msg = new \Google_Service_Gmail_Message();
            $msg->setRaw($mime);
            // Print the labels in the user's account.
            $gmailAPI->sendMessage($service,'me',$msg);
        }else{      
           $redirect_uri=$gmailAPI->createGoogleUrl();
           header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
           die();
        }

        die();


    }
}

错误

这是我得到的错误

Type: Google_Service_Exception
Code: 401
Message: { "error": { "errors": [ { "domain": "global", "reason": "authError", "message": "Invalid Credentials", "locationType": "header", "location": "Authorization" } ], "code": 401, "message": "Invalid Credentials" } }
File: D:\xampp\htdocs\slim_tutorial\home\linearct\checkin\vendor\google\apiclient\src\Google\Http\REST.php
Line: 118

但是,如果我在客户端的身份验证方法上使用 var_dump,我会得到

array(2) {
  ["error"]=>
  string(13) "invalid_grant"
  ["error_description"]=>
  string(11) "Bad Request"
}

标签: phpgoogle-api

解决方案


推荐阅读