前置作業
- 首先在 Google Cloud 頁面,建立一個專案。
- 啟用 Google+ API。
- 設定 OAuth 同意畫面
- 建立 OAuth 用戶端
實作
後端
安裝依賴套件。
1
| composer require laravel/socialite
|
修改 .env
檔。
1 2 3
| GOOGLE_CLIENT_ID=your-client-id GOOGLE_CLIENT_SECRET=your-client-secret GOOGLE_REDIRECT_URI=http:
|
修改 config/services.php
檔。
1 2 3 4 5
| 'google' => [ 'client_id' => env('GOOGLE_CLIENT_ID'), 'client_secret' => env('GOOGLE_CLIENT_SECRET'), 'redirect' => env('GOOGLE_REDIRECT_URI'), ],
|
修改 database/migrations/create_package_user_table.php
檔。
1 2 3 4 5 6 7 8
| public function up(): void { Schema::create('users', function (Blueprint $table) { $table->string('password')->nullable(); }); }
|
修改 routes/api.php
檔。
1 2 3 4
| Route::prefix('auth/{provider}')->group(function () { Route::get('/', [ProviderController::class, 'redirect']); Route::get('callback', [ProviderController::class, 'handleCallback']); });
|
新增 app/Http/Controllers/Auth/GoogleController.php
檔。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| <?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller; use App\Models\User; use Illuminate\Http\Request; use Illuminate\Http\Response; use Laravel\Socialite\Facades\Socialite; use Laravel\Socialite\Two\AbstractProvider;
class ProviderController extends Controller { private $available = [ 'google', ];
public function redirect($provider) { if (!in_array($provider, $this->available)) { abort(Response::HTTP_NOT_FOUND); }
$provider = Socialite::driver($provider);
return $provider->stateless()->redirect(); }
public function handleCallback(Request $request, $provider) { if (!in_array($provider, $this->available)) { abort(Response::HTTP_NOT_FOUND); }
$request->validate([ 'code' => 'required', ]);
$provider = Socialite::driver($provider);
$providerUser = $provider->stateless()->user();
$user = User::query()->firstOrCreate([ 'email' => $providerUser->email, ], [ 'name' => $providerUser->name, 'email' => $providerUser->email, ]);
$token = $user->createToken('')->plainTextToken;
return response()->json(compact('token')); } }
|
前端
建立一個跳轉函式,當使用者按下按鈕後,頁面將由後端帶往至 Google 登入頁面。。
1 2 3
| const signInWithGoogle = () => { window.location.href = 'http://localhost:8000/api/auth/google'; };
|
新增 pages/auth/google/callback.vue
檔。當使用者從 Google 登入頁面導回前端時,前端就可以將 code
發送至後端處理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <script setup> const route = useRoute();
const { code } = route.query;
const { data } = await useFetch('http://127.0.0.1:8000/api/auth/google/callback', { ssr: false, method: 'GET', params: { provider: 'google', code, }, });
console.log(data.value); </script>
<template> <div /> </template>
|
參考資料