iT邦幫忙

2024 iThome 鐵人賽

DAY 28
0
Modern Web

後端菜雞仔想學 Laravel系列 第 28

Laravel Socialite:方便處理第三方登入的串接

  • 分享至 

  • xImage
  •  

Laravel Socialite

是 Laravel 提供的一個非常方便的套件,專門用來處理第三方登入的功能,像是 Google、Facebook、GitHub、Line 等各種平台的 OAuth 認證流程。

使用 Socialite 讓開發者能夠簡單實作這些平台的登入,免去自己手動處理繁瑣的 OAuth 認證邏輯。

主要功能

它的作用是幫你處理跟第三方平台的對接,包括生成登入連結、接收授權碼、拿取使用者資料等。

當使用者成功登入後,你可以取得他們的資料,例如:email、名字、大頭貼等,然後決定要讓他登入還是幫他註冊新帳號。

使用 Socialite 處理 Line 第三方登入的串接

我的步驟:

  1. 註冊 Line 開發者帳號並建立 Line Login Channel
  2. 取得 Channel ID 跟密鑰
  3. 設定 callBack 的 URL
  4. 安裝好 Laravel socialiite、socialiteproviders/line 套件
  5. 設定 Line 的串接資料:config/services.php跟 .env檔案
  6. 在 users 表裡多新增一個 line_id 欄位
  7. 新增一個 Line第三方登入的 Controller
  8. 設定路由

步驟 1-3 是昨天做的前置作業,今天來接著做步驟 4-8!

使用 Composer 來安裝套件:

composer require laravel/socialite
composer require socialiteproviders/line

更新 config/services.php:

'line' => [
    'client_id' => env('LINE_CLIENT_ID'),
    'client_secret' => env('LINE_CLIENT_SECRET'),
    'redirect' => env('LINE_REDIRECT_URI'),
],

設定 OAuth 憑證

每個第三方平台都會提供給你一組 client_id 和 client_secret(也就是應用程式的身份憑證)。
你需要到這些平台的開發者後台註冊應用程式,然後把憑證填到 .env 檔案。

  • 昨天有從 Line Developers 平台取得的 Channel ID 和 Channel Secret 就是憑證。

更新 .env 檔案:

LINE_CLIENT_ID=你的-Line-Channel-ID
LINE_CLIENT_SECRET=你的-Line-Channel-Secret
LINE_REDIRECT_URI=http://你的網站.com/auth/line/callback
  • 務必確認 LINE_REDIRECT_URI 跟你在 Line Developers 平台設定的 callback URL 一致。

新增一個 line_id 欄位

在 users 表中新增一個 line_id 欄位來儲存 Line 的使用者 ID。
這樣可以追蹤使用者是否透過 Line 登入。

新增一個 Migration:

php artisan make:migration add_line_id_to_users_table --table=users

編輯 Migration:

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->string('line_id')->nullable()->unique();
    });
}

public function down()
{
    Schema::table('users', function (Blueprint $table) {
        $table->dropColumn('line_id');
    });
}

執行 Migration:

php artisan migrate

要再指派一位店長,還是使用原有的店長?

目前狀況:

已經有 AuthController 使用 JWT 進行身份驗證,要處理 Line 第三方登入目前想到有以下 2 個方法做選擇。

  1. 新增專用的 LineLoginController:
    • 專門處理 Line 登入相關的邏輯。
    • 好處是清晰分離不同的登入邏輯,讓每個 Controller 負責不同的登入方式。
  2. 擴展現有的 AuthController:
    • 可以保持登入邏輯集中在一個 Controller 中。
    • 這種方式適合希望所有身份驗證邏輯集中管理的情況。

我覺得新增一個 LineLoginController 專門處理 Line 登入相關的邏輯比較好維護,Controller 也比較不會太肥XD
但大家可以依照自己的需求選擇適合的方法。

再指派一位店長!

php artisan make:controller LineLoginController

Line 第三方登入邏輯

在 LineLoginController 加入以下方法:

  • 處理重定向到 Line 登入頁面
  • 處理 Line 回調的邏輯

LineLoginController.php:

<?php

namespace App\Http\Controllers;

use Laravel\Socialite\Facades\Socialite;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Tymon\JWTAuth\Facades\JWTAuth;

class LineLoginController extends Controller
{
    // 導向到 Line 登入頁面
    public function redirectToLine()
    {
        // 使用 Socialite 驅動的 'line' 來處理重定向到 Line 的登入頁面
        return Socialite::driver('line')->redirect();
    }

    // Line 登入後的回調邏輯
    public function handleLineCallback()
    {
        try {
            // 從 Line 回調中取得使用者資料
            $lineUser = Socialite::driver('line')->user();

            // 根據 Line ID 查找是否已有會員帳號
            $user = User::where('line_id', $lineUser->id)->first();

            if (!$user) {
                // 如果會員帳號不存在,則創建新會員帳號
                $user = User::create([
                    'name' => $lineUser->name, // 使用 Line 的名稱
                    'email' => $lineUser->email, // 使用 Line 提供的電子郵件
                    'line_id' => $lineUser->id, // 將 Line 的 ID 存入資料庫
                    'role' => '一般會員', // 預設為一般會員
                ]);
            }

            // 使用 JWT 與該使用者對應的 token 來進行登入
            $token = JWTAuth::fromUser($user);

            // 回傳包含 token 的 JSON 回應
            return response()->json(['token' => $token]);

        } catch (\Exception $e) {
            // 如果有任何錯誤,回傳錯誤訊息
            return response()->json(['error' => 'Line 登入失敗', 'message' => $e->getMessage()], 500);
        }
    }
}

Socialite::driver('line')

driver('line') 是在告訴 Socialite,我這次要處理的是 Line 的登入,請幫我準備好相關設定。

簡單來說,就是在設定好 Line 登入的「通道」,準備接下來把使用者送去 Line 的登入畫面,讓他們授權。

Socialite::driver('line')->user()

->user() 是用來處理當使用者完成 Line 授權後,去 Line 那邊把使用者的資料拿回來。
這裡的資料可能包含使用者的名字、email、Line 的 ID 等等。

流程大概是這樣:

  1. 使用者點擊「使用 Line 登入」。
  2. Socialite::driver('line') 會送到 Line 的登入頁面,讓使用者輸入 Line 帳號、密碼。
  3. 使用者登入成功,Line 會回傳一個授權碼給你的網站。
  4. Socialite::driver('line')->user() 就會用這個授權碼,向 Line 取得使用者的詳細資料。

這裡真的是大魔王!!!

可能會有很多原因導致無法取得使用者的資料,但一開始又不曉得是什麼原因導致錯誤,需要很有耐心的一一排查><
明天測試時可以再跟大家分享一下我排查的過程。(拭淚)

分配店員:設定路由

在 routes/web.php 中定義兩個路由:

  • 跳轉到 Line 登入頁面的路由
  • 處理 Line 認證回來後的 callback 路由。

web.php:

use App\Http\Controllers\LineLoginController;

Route::middleware(['web'])->group(function () {
    Route::get('/login/line', [LineLoginController::class, 'redirectToLine']);
    Route::get('/login/line/callback', [LineLoginController::class, 'handleLineCallback']);
});

更多相關資訊可以參考官方文件:


上一篇
第三方登入:不用花時間註冊會員好方便!
下一篇
測試 Line 第三方登入:出現問題的時候先深呼吸再吐氣!
系列文
後端菜雞仔想學 Laravel30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言