2013-04-09 26 views
8

Tôi đã theo dõi lại một lần nữa THIS TUTORIAL để tải lên tệp trên Google Drive bằng php, trực tiếp từ REMOTE SERVER của tôi: vì vậy tôi đã tạo Dự án API mới từ Google API Console, đã bật dịch vụ API Drive, yêu cầu OAuth ID và khách hàng bí mật, đã viết chúng trong một kịch bản, sau đó tải nó cùng với Google APIs Client Library for PHP thư mục để http://www.MYSERVER.com/script1.php này, để lấy đang Auth:Tự động làm mới mã thông báo bằng cách sử dụng google drive api bằng tập lệnh php

<?php 

require_once 'google-api-php-client/src/Google_Client.php'; 
require_once 'google-api-php-client/src/contrib/Google_DriveService.php'; 

$drive = new Google_Client(); 

$drive->setClientId('XXX'); // HERE I WRITE MY Client ID 

$drive->setClientSecret('XXX'); // HERE I WRITE MY Client Secret 

$drive->setRedirectUri('urn:ietf:wg:oauth:2.0:oob'); 

$drive->setScopes(array('https://www.googleapis.com/auth/drive')); 

$gdrive = new Google_DriveService($drive); 

$url = $drive->createAuthUrl(); 
$authorizationCode = trim(fgets(STDIN)); 

$token = $drive->authenticate($authorizationCode); 

?> 

Khi tôi ghé thăm http://www.MYSERVER.com/script1.php tôi phép uỷ quyền và nhận được Auth mã mà tôi có thể viết trong tập lệnh thứ hai. Sau đó, tôi tải nó lên http://www.MYSERVER.com/script2.php, người trông giống như:

<?php 

require_once 'google-api-php-client/src/Google_Client.php'; 
require_once 'google-api-php-client/src/contrib/Google_DriveService.php'; 

$drive = new Google_Client(); 

$drive->setClientId('X'); // HERE I WRITE MY Client ID 
$drive->setClientSecret('X'); // HERE I WRITE MY Client Secret 
$drive->setRedirectUri('urn:ietf:wg:oauth:2.0:oob'); 
$drive->setScopes(array('https://www.googleapis.com/auth/drive')); 

$gdrive = new Google_DriveService($drive); 

$_GET['code']= 'X/XXX'; // HERE I WRITE AUTH CODE RETRIEVED AFTER RUNNING REMOTE script.php 

file_put_contents('token.json', $drive->authenticate()); 

$drive->setAccessToken(file_get_contents('token.json')); 

$doc = new Google_DriveFile(); 

$doc->setTitle('Test Drive'); 
$doc->setDescription('Document'); 
$doc->setMimeType('text/plain'); 

$content = file_get_contents('drive.txt'); 

$output = $gdrive->files->insert($doc, array(
     'data' => $content, 
     'mimeType' => 'text/plain', 
    )); 

print_r($output); 

?> 

Vâng, bây giờ các tập tin được tải lên drive.txt trên Google Drive và cấu trúc của tập tin token.json của tôi là một loại:

{"access_token":"XXX","token_type":"Bearer","expires_in":3600,"refresh_token":"YYY","created":1365505148} 

Bây giờ, như bạn có thể tưởng tượng tôi có thể gọi script2.php và tải lên tập tin cho đến một thời gian nhất định. Cuối cùng, vấn đề là: Tôi không muốn mã thông báo hết hạn, tôi không muốn cho phép ủy quyền mỗi lần hết hạn (gọi lại script1.php): Tôi cần gọi script2.php định kỳ trong suốt trong ngày, để tải lên tệp của tôi tự động, mà không có sự tương tác của người dùng. Vì vậy, cách tốt nhất để tự động làm mới mã thông báo mãi mãi trong ngữ cảnh này là gì? Tôi có cần một tập lệnh khác không? Tôi có thể thêm một số mã vào script2.php không? hoặc sửa đổi tệp token.json? Và tôi có thể đọc thời gian còn lại trước khi mã thông báo hết hạn? Cảm ơn!

Trả lời

30

Bạn không phải định kỳ yêu cầu mã thông báo truy cập. Nếu bạn có một refresh_token, PHP khách hàng sẽ tự động có được một mã thông báo truy cập mới cho bạn.

Để lấy một refresh_token, bạn cần phải thiết lập access_type để "ẩn" và yêu cầu ẩn quyền truy cập:

$drive->setAccessType('offline'); 

Khi bạn nhận được một code,

$_GET['code']= 'X/XXX'; 
$drive->authenticate(); 

// persist refresh token encrypted 
$refreshToken = $drive->getAccessToken()["refreshToken"]; 

Đối với các yêu cầu trong tương lai , đảm bảo mã thông báo được làm mới luôn được đặt:

$tokens = $drive->getAccessToken(); 
$tokens["refreshToken"] = $refreshToken; 
$drive->setAccessToken(tokens); 

Nếu bạn muốn có một lực lượng truy cập refresh dấu hiệu, bạn có thể làm điều đó bằng cách gọi refreshToken:

$drive->refreshToken($refreshToken); 

Hãy coi chừng, refresh_token sẽ được trả lại chỉ trên $drive->authenticate() đầu tiên, bạn cần phải lưu trữ vĩnh viễn nó. Để có được một tệp refresh_token mới, bạn cần thu hồi mã thông báo hiện có của mình và bắt đầu lại quá trình xác thực.

Truy cập ngoại tuyến được giải thích chi tiết trên Google's OAuth 2.0 documentation.

+0

Cảm ơn bạn @Burcu, điểm được nói cách của bạn "Nếu mã thông báo truy cập của bạn hết hạn": KHI tÔI cÓ THỂ XEM rằng thẻ truy cập của tôi hết hạn? nó có vĩnh viễn hay không? – Huxley

+0

@Huxley, nó sẽ ném một 'Google_AuthException'. Mặt khác, thư viện máy khách này sẽ tự động làm mới mã thông báo truy cập nếu mã thông báo hiện tại sắp hết hạn. Vì vậy, thông thường bạn sẽ không bao giờ thấy lỗi xác thực. Tôi đang chỉnh sửa câu trả lời của mình ở trên. –

+0

Tôi đã truy xuất refresh_token và access_token từ OAuth 2.0 Playground console và lưu nó trong tệp tin token.json của tôi: nó giống nhau? chúng có vĩnh viễn không? – Huxley

1

Sau khi làm hỏng rất nhiều, tôi đã làm việc này.Tôi đang sử dụng một tập tin/script để có mã thông báo ẩn và sau đó một lớp học để làm mọi thứ với các api:

require_once 'src/Google/autoload.php'; // load library 

session_start(); 

$client = new Google_Client(); 
// Get your credentials from the console 
$client->setApplicationName("Get Token"); 
$client->setClientId('...'); 
$client->setClientSecret('...'); 
$client->setRedirectUri('...'); // self redirect 
$client->setScopes(array('https://www.googleapis.com/auth/drive.file')); 
$client->setAccessType("offline"); 
$client->setApprovalPrompt('force'); 



if (isset($_GET['code'])) { 
    $client->authenticate($_GET['code']); 
    $_SESSION['token'] = $client->getAccessToken(); 
    $client->getAccessToken(["refreshToken"]); 
    $redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']; 
    header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL)); 
    return; 
} 

if (isset($_SESSION['token'])) { 
    $client->setAccessToken($_SESSION['token']); 
} 

if (isset($_REQUEST['logout'])) { 
    unset($_SESSION['token']); 
    $client->revokeToken(); 
} 


?> 
<!doctype html> 
<html> 
    <head><meta charset="utf-8"></head> 
    <body> 
     <header><h1>Get Token</h1></header> 
     <?php 
     if ($client->getAccessToken()) { 
      $_SESSION['token'] = $client->getAccessToken(); 
      $token = json_decode($_SESSION['token']); 
      echo "Access Token = " . $token->access_token . '<br/>'; 
      echo "Refresh Token = " . $token->refresh_token . '<br/>'; 
      echo "Token type = " . $token->token_type . '<br/>'; 
      echo "Expires in = " . $token->expires_in . '<br/>'; 
      echo "Created = " . $token->created . '<br/>'; 
      echo "<a class='logout' href='?logout'>Logout</a>"; 
      file_put_contents("token.txt",$token->refresh_token); // saving access token to file for future use 
     } else { 
      $authUrl = $client->createAuthUrl(); 
      print "<a class='login' href='$authUrl'>Connect Me!</a>"; 
     } 
     ?> 
    </body> 
</html> 

Bạn có thể nạp thẻ làm mới từ tập tin và sử dụng nó khi cần thiết để truy cập ẩn:

class gdrive{ 

function __construct(){ 
     require_once 'src/Google/autoload.php'; 
     $this->client = new Google_Client(); 
} 

function initialize(){ 
     echo "initializing class\n"; 
     $client = $this->client; 
     // credentials from google console 
     $client->setClientId('...'); 
     $client->setClientSecret('...'); 
     $client->setRedirectUri('...'); 

     $refreshToken = file_get_contents(__DIR__ . "/token.txt"); // load previously saved token 
     $client->refreshToken($refreshToken); 
     $tokens = $client->getAccessToken(); 
     $client->setAccessToken($tokens); 

     $this->doSomething(); // go do something with the api  
    } 
} 

More đây: https://github.com/yannisg/Google-Drive-Uploader-PHP