首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Google API OAuth 2.0 CURL返回“缺少必需的参数: grant_type”

Google API OAuth 2.0 CURL返回“缺少必需的参数: grant_type”
EN

Stack Overflow用户
提问于 2011-11-19 23:12:33
回答 6查看 13.2K关注 0票数 4

我正在尝试为一个web服务器应用程序实现谷歌的OAuth 2.0身份验证。

我可以从Google ok获取代码,但是当我发回这段代码并尝试获取访问令牌时,它总是给我一个错误“必需的参数缺失: grant_type。错误400”,即使grant_type在那里。

另外,如果我指定content-length为0以外的任何值,它还会抛出其他错误。

下面是执行这个curl post的代码:

代码语言:javascript
运行
AI代码解释
复制
$url = 'https://accounts.google.com/o/oauth2/token';
$ch = curl_init($url);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);  
curl_setopt($ch, CURLOPT_FAILONERROR, false);  
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); 

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/x-www-form-urlencoded',
    'Content-length: 0'
));

curl_setopt($ch, CURLOPT_POSTFIELDS, array( 
    'code='. urlencode($code),
    'client_id=' . urlencode($clientID),
    'client_secret=' . urlencode($clientSecret),
    'redirect_uri=http%3A%2F%2Flocalhost%2Fexperiments%2FnewGALogin.php',
    'grant_type=authorization_code'
)); 
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-11-20 00:50:02

试一试

代码语言:javascript
运行
AI代码解释
复制
curl_setopt($ch, CURLOPT_POSTFIELDS, array( 
    'code' => $code,
    'client_id' => $clientID,
    'client_secret' => $clientSecret,
    'redirect_uri' => 'http%3A%2F%2Flocalhost%2Fexperiments%2FnewGALogin.php',
    'grant_type' => 'authorization_code'
)); 

代码语言:javascript
运行
AI代码解释
复制
curl_setopt($ch, CURLOPT_POSTFIELDS,
    'code=' . urlencode($code) . '&' .
    'client_id=' . urlencode($clientID) . '&' .
    'client_secret=' . urlencode($clientSecret) . '&' .
    'redirect_uri=http%3A%2F%2Flocalhost%2Fexperiments%2FnewGALogin.php' . '&' .
    'grant_type=authorization_code'
); 
票数 7
EN

Stack Overflow用户

发布于 2015-04-10 20:20:46

经过研究这个问题,似乎grant_type在数组格式中不被接受。(是的,查询字符串方法可以工作,但是构建起来很麻烦。)

如果您热衷于将POST字段保留在数组中,那么将http_build_query()添加到数组中是可行的。

代码语言:javascript
运行
AI代码解释
复制
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array( 
    'code' => $code,
    'client_id' => $clientID,
    'client_secret' => $clientSecret,
    'redirect_uri' => 'http%3A%2F%2Flocalhost%2Fexperiments%2FnewGALogin.php',
    'grant_type' => 'authorization_code'
))); 
票数 1
EN

Stack Overflow用户

发布于 2016-01-05 21:48:58

我试图在这里提供的原始问题和答案中使用PHP代码,并不断收到来自Google token服务器的关于丢失的"grant_type“的投诉,尽管它肯定是被传入的。原来问题出在CURLOPT_HTTPHEADER不喜欢/不需要“Content-length:0”。希望这个完整的工作代码能让其他人避免同样令人头疼的事情。

代码语言:javascript
运行
AI代码解释
复制
// This is what Google's OAUTH server sends to you
$code = $_GET['code'];

// These come from your client_secret.json file
$clientID = "your client id.apps.googleusercontent.com";
$clientSecret = "your client secret";
$redirectURI = "your redirect URI";
$token_uri = 'https://accounts.google.com/o/oauth2/token';


$ch = curl_init($token_uri);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);  
curl_setopt($ch, CURLOPT_FAILONERROR, false);  
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/x-www-form-urlencoded'
));

// Build the URLEncoded post data
$postFields = http_build_query(array( 
    'client_secret' => $clientSecret,
    'grant_type' => 'authorization_code',
    'redirect_uri' => $redirectURI,
    'client_id' => $clientID,
    'code' => $code
));
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields); 

$response = curl_exec($ch);

// Save response, especially the "refresh_token"
$pathToAccessToken = "/your/path/to/access_token.json";
file_put_contents($pathToAccessToken, $response);

仅供参考,响应JSON如下所示:

代码语言:javascript
运行
AI代码解释
复制
{
  "access_token" : "xxxWhateverGibberish", 
  "token_type" : "Bearer", 
  "expires_in" : 3600, 
  "refresh_token" : "yyyMoreGibberish" 
}

之后,我可以使用如下代码成功查询Calendar (我最初的OAuth请求调用的API作用域):

代码语言:javascript
运行
AI代码解释
复制
function getClient() {
  $client = new Google_Client();
  $client->setApplicationName(APPLICATION_NAME);
  $client->setScopes(SCOPES);
  $client->setAuthConfigFile(CLIENT_SECRET_PATH);
  $client->setAccessType('offline');

  // Load previously authorized credentials from a file.
  $pathToAccessToken = "/your/path/to/access_token.json";
  $accessToken = file_get_contents($pathToAccessToken);
  $client->setAccessToken($accessToken);

  // Refresh the token if it's expired.
  if ($client->isAccessTokenExpired()) {
    $client->refreshToken($client->getRefreshToken());
    file_put_contents($pathToAccessToken, $client->getAccessToken());
  }

  return $client;
}

$client = getClient();
$service = new Google_Service_Calendar($client);

// Print the next 10 events on the user's calendar.
$calendarId = 'primary';
$optParams = array(
      'maxResults' => 10,
      'orderBy' => 'startTime',
      'singleEvents' => TRUE,
      'timeMin' => date('c'),
);
$results = $service->events->listEvents($calendarId, $optParams);

if (count($results->getItems()) == 0) {
    print "No upcoming events found.\n";
} else {
    print "Upcoming events:\n";
    foreach ($results->getItems() as $event) {
        $start = $event->start->dateTime;
        if (empty($start)) {
          $start = $event->start->date;
        }
        printf("%s (%s)\n", $event->getSummary(), $start);
    }
}       
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8198072

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档