😆Setup a Laravel Storage driver with Google Drive API (ok)

https://gist.github.com/sergomet/f234cc7a8351352170eb547cccd65011#setup-a-laravel-storage-driver-with-google-drive-api

Souce tham khảo. https://khamphukhoacaugiay.vn/

Source code

Đã thực thiện thành công

C:\xampp82\htdocs\lva4\database\migrations\2014_10_12_000000_create_users_table.php

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
  /**
   * Run the migrations.
   *
   * @return void
   */
  public function up()
  {
    Schema::create('users', function (Blueprint $table) {
      $table->id();
      $table->string('name');
      $table->string('email')->unique();
      $table->timestamp('email_verified_at')->nullable();
      $table->text('access_token')->nullable(); // ADD THIS COLUMN
      $table->string('password');
      $table->rememberToken();
      $table->timestamps();
    });
  }
  /**
   * Reverse the migrations.
   *
   * @return void
   */
  public function down()
  {
    Schema::dropIfExists('users');
  }
}

C:\xampp82\htdocs\lva4\app\Models\User.php

<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
  use HasApiTokens, HasFactory, Notifiable;
  /**
   * The attributes that are mass assignable.
   *
   * @var array
   */
  protected $fillable = [
    'name',
    'email',
    'password',
    'access_token' // ADD TOKEN PROPERTY HERE
  ];
  /**
   * The attributes that should be hidden for serialization.
   *
   * @var array
   */
  protected $hidden = [
    'password',
    'remember_token',
  ];
  /**
   * The attributes that should be cast.
   *
   * @var array
   */
  protected $casts = [
    'email_verified_at' => 'datetime',
  ];
}

C:\xampp82\htdocs\lva4\routes\web.php

<?php
use App\Http\Controllers\GoogleDriveController;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "web" middleware group. Make something great!
|
*/
Route::get('/', function () {
  return view('welcome');
});
Auth::routes();
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
Route::get('google/login', [GoogleDriveController::class, 'googleLogin'])->name('google.login');
Route::get('google-drive/file-upload', [GoogleDriveController::class, 'googleDriveFilePpload'])->name('google.drive.file.upload');

C:\xampp82\htdocs\lva4\app\Http\Controllers\GoogleDriveController.php

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
class GoogleDriveController extends Controller
{
  public $gClient;
  function __construct()
  {
    $this->gClient = new \Google_Client();
    $this->gClient->setApplicationName('Web client 1'); // ADD YOUR AUTH2 APPLICATION NAME (WHEN YOUR GENERATE SECRATE KEY)
    $this->gClient->setClientId('710157078117-9t8ppso74lgg3f90nrf24nk8tp8t4ula.apps.googleusercontent.com');
    $this->gClient->setClientSecret('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');
    $this->gClient->setRedirectUri('https://lva4.com/google/login');
    $this->gClient->setDeveloperKey('1KZ5fYZ9McCeMrSr2YE3o10ywODPpTkmN');
    $this->gClient->setScopes(array(
      'https://www.googleapis.com/auth/drive.file',
      'https://www.googleapis.com/auth/drive'
    ));
    $this->gClient->setAccessType("offline");
    $this->gClient->setApprovalPrompt("force");
  }
  public function googleLogin(Request $request)
  {
    $google_oauthV2 = new \Google_Service_Oauth2($this->gClient);
    if ($request->get('code')) {
      $this->gClient->authenticate($request->get('code'));
      $request->session()->put('token', $this->gClient->getAccessToken());
    }
    if ($request->session()->get('token')) {
      $this->gClient->setAccessToken($request->session()->get('token'));
    }
    if ($this->gClient->getAccessToken()) {
      //FOR LOGGED IN USER, GET DETAILS FROM GOOGLE USING ACCES
      $user = User::find(1);
      $user->access_token = json_encode($request->session()->get('token'));
      $user->save();
      dd("Successfully authenticated");
    } else {
      // FOR GUEST USER, GET GOOGLE LOGIN URL
      $authUrl = $this->gClient->createAuthUrl();
      return redirect()->to($authUrl);
    }
  }
  public function googleDriveFilePpload()
  {
    $service = new \Google_Service_Drive($this->gClient);
    $user = User::find(1);
    $this->gClient->setAccessToken(json_decode($user->access_token, true));
    if ($this->gClient->isAccessTokenExpired()) {
      // SAVE REFRESH TOKEN TO SOME VARIABLE
      $refreshTokenSaved = $this->gClient->getRefreshToken();
      // UPDATE ACCESS TOKEN
      $this->gClient->fetchAccessTokenWithRefreshToken($refreshTokenSaved);
      // PASS ACCESS TOKEN TO SOME VARIABLE
      $updatedAccessToken = $this->gClient->getAccessToken();
      // APPEND REFRESH TOKEN
      $updatedAccessToken['refresh_token'] = $refreshTokenSaved;
      // SET THE NEW ACCES TOKEN
      $this->gClient->setAccessToken($updatedAccessToken);
      $user->access_token = $updatedAccessToken;
      $user->save();
    }
    $fileMetadata = new \Google_Service_Drive_DriveFile(array(
      'name' => 'Webappfix',             // ADD YOUR GOOGLE DRIVE FOLDER NAME
      'mimeType' => 'application/vnd.google-apps.folder'
    ));
    $folder = $service->files->create($fileMetadata, array('fields' => 'id'));
    printf("Folder ID: %s\n", $folder->id);
    $file = new \Google_Service_Drive_DriveFile(array('name' => 'cdrfile.jpg', 'parents' => array($folder->id)));
    $result = $service->files->create($file, array(
      'data' => file_get_contents(public_path('Screenshot_1.png')), // ADD YOUR FILE PATH WHICH YOU WANT TO UPLOAD ON GOOGLE DRIVE
      'mimeType' => 'application/octet-stream',
      'uploadType' => 'media'
    ));
    // GET URL OF UPLOADED FILE
    $url = 'https://drive.google.com/open?id=' . $result->id;
    dd($result);
  }
}

Cấu hình lấy ở đây https://console.cloud.google.com/apis/credentials/oauthclient/710157078117-9t8ppso74lgg3f90nrf24nk8tp8t4ula.apps.googleusercontent.com?project=test-gd-api

https://developers.google.com/oauthplayground

Kết quả:

Log in to your Google Account and go to this website:

https://console.developers.google.com/

Create a new project using the dropdown at the top.

After you enter a name, it takes a few seconds before the project is successfully created on the server.

Make sure you have the project selected at the top.

Then go to Library and click on "Drive API" under "Google Apps APIs".

And then Enable it.

Then, go to "Credentials" and click on the tab "OAuth Consent Screen". Fill in a "Product name shown to users" and Save it. Don't worry about the other fields.

Then go back to Credentials, click the button that says "Create Credentials" and select "OAuth Client ID".

Choose "Web Application" and give it a name.

Enter your "Authorized redirect URIs", preferably your test URL (http://mysite.dev) and your production URL (https://mysite.com) - or create a separate production key later. Also add https://developers.google.com/oauthplayground temporarily, because you will need to use that in the next step.

Click Create and take note of your Client ID and Client Secret.

Now head to https://developers.google.com/oauthplayground.

Make sure you added this URL to your Authorized redirect URIs in the previous step.

In the top right corner, click the settings icon, check "Use your own OAuth credentials" and paste your Client ID and Client Secret.

In step 1 on the left, scroll to "Drive API v3", expand it and check each of the scopes.

Click "Authorize APIs" and allow access to your account when prompted.

When you get to step 2, check "Auto-refresh the token before it expires" and click "Exchange authorization code for tokens".

When you get to step 3, click on step 2 again and you should see your refresh token.

If you want to store files in your Google Drive root directory, then the folder ID can be null. Else go into your Drive and create a folder.

Because Google Drive allows for duplicate names, it identifies each file and folder with a unique ID. If you open your folder, you will see the Folder ID in the URL.

Pull in Flysystem Adapter for Google Drive:

composer require nao-pon/flysystem-google-drive:~1.1

Add the storage disk configuration to config/filesystem.php:

return [
  
    // ...
  
    'cloud' => 'google', // Optional: set Google Drive as default cloud storage
    
    'disks' => [
        
        // ...
        
        'google' => [
            'driver' => 'google',
            'clientId' => env('GOOGLE_DRIVE_CLIENT_ID'),
            'clientSecret' => env('GOOGLE_DRIVE_CLIENT_SECRET'),
            'refreshToken' => env('GOOGLE_DRIVE_REFRESH_TOKEN'),
            'folderId' => env('GOOGLE_DRIVE_FOLDER_ID'),
        ],
        
        // ...
        
    ],
    
    // ...
];

And update your .env file:

GOOGLE_DRIVE_CLIENT_ID=xxx.apps.googleusercontent.com
GOOGLE_DRIVE_CLIENT_SECRET=xxx
GOOGLE_DRIVE_REFRESH_TOKEN=xxx
GOOGLE_DRIVE_FOLDER_ID=null

Save GoogleDriveServiceProvider.php to app/Providers and add it to the providers array in config/app.php:

App\Providers\GoogleDriveServiceProvider::class,

Now you should be up and running:

Route::get('test', function() {
    Storage::disk('google')->put('test.txt', 'Hello World');
});

Last updated