【问题标题】:Is there a way to get OAuth 2.0 token directly with CURL?有没有办法直接使用 CURL 获取 OAuth 2.0 令牌?
【发布时间】:2020-03-02 01:12:20
【问题描述】:

我想获取一个访问令牌来调用 Google Directory API。我看过几篇关于 PHP Curl 代码的帖子,但每次都必须有一个人工操作来允许访问,然后才能获得访问令牌。有没有办法发出 CURL 请求并直接获取访问令牌?

这是我目前的代码:

 define("CALLBACK_URL", "http://localhost/los/index");
define("AUTH_URL", "https://accounts.google.com/o/oauth2/auth");
 define("ACCESS_TOKEN_URL", "https://oauth2.googleapis.com/token");
define("CLIENT_ID", "**.apps.googleusercontent.com");
 define("CLIENT_SECRET", "**");
 define("SCOPE", "https://www.googleapis.com/auth/admin.directory.device.chromeos"); 

function getToken(){
  $curl = curl_init();

  $params = array(
CURLOPT_URL =>  
ACCESS_TOKEN_URL."?"."&grant_type=authorization_code"."&client_id=". 
CLIENT_ID."&client_secret=". CLIENT_SECRET."&redirect_uri=". CALLBACK_URL,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_MAXREDIRS => 10,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_ENCODING => '',
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_NOBODY => false, 
CURLOPT_HTTPHEADER => array(
  "cache-control: no-cache",
  "Content-Length: 0",
  "content-type: application/x-www-form-urlencoded",
  "accept: *",
      "accept-encoding: gzip, deflate",
    ),
  );

  curl_setopt_array($curl, $params);

   $response = curl_exec($curl);
   $err = curl_error($curl);
    echo $response;
  curl_close($curl);

 if ($err) {
echo "cURL Error #01: " . $err;
   } else {
$response = json_decode($response, true);    
if(array_key_exists("access_token", $response)) return $response;
if(array_key_exists("error", $response)) echo $response["error_description"];
echo "cURL Error #02: Something went wrong! Please contact admin.";
  } 
 }

当我运行它时,我收到以下错误消息:

{ "error": "invalid_request", "error_description": "Missing required parameter: code" }Missing required parameter: codec

【问题讨论】:

    标签: php authentication curl token access-token


    【解决方案1】:

    在用户授权同意屏幕后,我刚刚遇到了使用 PHP cURL 从 Google API 返回的 http 代码获取访问令牌的类似问题。这是我冗长的答案:

    从最不重要到最重要:您应该首先在 if 条件之后固定括号:

        if (array_key_exists("access_token", $response)) {
          return $response
        } elseif (array_key_exists("error", $response)) {
          echo $response["error_description"];
          echo "cURL Error #02: Something went wrong! Please contact admin.";
        }
    

    出现“Missing required parameter: code”的错误信息是因为您需要在客户端授权您的应用程序后发布url中返回的代码。你可以这样做:

        CURLOPT_URL => ACCESS_TOKEN_URL."?"."&code=".$_GET['code']."&grant_type=authorization_code"."&client_id=".CLIENT_ID."&client_secret=". CLIENT_SECRET."&redirect_uri=".CALLBACK_URL,
    

    为了使其更具语义性,您可以在此之前定义 $authorization 代码变量:

        $authorizationCode = $_GET['code'];
    

    最后,最重要的部分是要从 Google 获取访问令牌,您需要使用文档中所示的 cURL post 方法:

    https://developers.google.com/identity/protocols/oauth2/web-server#exchange-authorization-code

    您可以使用 PHP cURL 执行此命令:

        curl_setopt( $ch, CURLOPT_POST, 1);
    

    但是您需要将您的 URL 分成两部分:主机和要发布的字段。为了便于阅读,您可以将端点和字段设置为变量:

        $endpoint = 'https://oauth2.googleapis.com/token';
    
        $fieldsToPost = array(
         // params for the endpoint
         'code' => $authorizationCode, //being that $authorizationCode = $_GET['code'];
         'client_id' => CLIENT_ID,
         'client_secret' => CLIENT_SECRET,
         'redirect_uri' => CALLBACK_URL,
         'grant_type' => 'authorization_code',
        );
    

    然后你可以使用 $enpoint 来设置 url 和 http_build_query() 来设置你的字段。最后,使您的代码适应对我有用的代码将如下所示:

        function getToken() {
    
         $endpoint = 'https://oauth2.googleapis.com/token';
    
         $fieldsToPost = array(
          // params for the endpoint
          'code' => $authorizationCode, //being that $authorizationCode = $_GET['code'];
          'client_id' => CLIENT_ID,
          'client_secret' => CLIENT_SECRET,
          'redirect_uri' => CALLBACK_URL,
          'grant_type' => 'authorization_code',
         );
    
         $curl = curl_init();
         curl_setopt($curl, CURLOPT_URL, $endpoint);
         curl_setopt($curl, CURLOPT_POST, 1);
         curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($fieldsToPost));
         curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
         curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE );   
    
         // get curl response, json decode it, and close curl
        $googleResponse = curl_exec($curl);
         $curl_error = curl_errno($curl);
         $googleResponse = json_decode( $googleResponse, TRUE );
         curl_close( $curl );
    
        return array( // return response data
          'url' => $endpoint . '?' . http_build_query( $params ),
          'endpoint' => $endpoint,
          'params' => $params,
          'has_errors' => isset( $googleResponse['error'] ) ? TRUE : FALSE, // b oolean for if an error occured
          'error_message' => isset( $googleResponse['error'] ) ? $googleResponse['error']['message'] : '', // error message
          'curl_error' => $curl_error, //curl_errno result
          'google_response' => $googleResponse // actual response from the call
         );
        }
    

    要检查响应,您可以使用以下打印功能来查看响应:

        if (isset($_GET['code'])) {
         $response = getToken();
         echo '<pre>';
         print_r($response);
         die();
        }
    

    我知道这已经很长时间了,您可能已经找到了解决方法,但我希望这对未来的项目仍然有用。干杯!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-03
      • 2016-05-08
      • 1970-01-01
      • 2014-05-11
      • 2014-05-03
      • 1970-01-01
      • 1970-01-01
      • 2019-10-17
      相关资源
      最近更新 更多