簡介 (Introduction)
除了傳統的表單式驗證外,Laravel 也提供一種簡單且方便的方法,透過 Laravel Socialite 與各種 OAuth 提供者進行驗證。Socialite 目前支援透過 Facebook、X、LinkedIn、Google、GitHub、GitLab、Bitbucket 與 Slack 等平台進行驗證。
[!NOTE] 社群維護的 Socialite Providers 網站提供了其他平台的整合套件。
安裝 (Installation)
要開始使用 Socialite,請使用 Composer 將此套件加入至專案相依性:
composer require laravel/socialite
升級 Socialite (Upgrading Socialite)
當升級到新的主要版本時,請務必詳細閱讀 升級指南。
設定 (Configuration)
在使用 Socialite 之前,你需要為應用程式所使用的 OAuth 提供者新增憑證。通常可在欲驗證服務的管理控制台建立「開發者應用程式」後取得這些憑證。
這些憑證應放在應用程式的 config/services.php 設定檔中,並根據所用提供者使用 facebook、x、linkedin-openid、google、github、gitlab、bitbucket、slack 或 slack-openid 等鍵值:
'github' => [
'client_id' => env('GITHUB_CLIENT_ID'),
'client_secret' => env('GITHUB_CLIENT_SECRET'),
'redirect' => 'http://example.com/callback-url',
],
[!NOTE] 如果
redirect選項包含相對路徑,系統會自動將其解析成完整的 URL。
身份驗證 (Authentication)
路由 (Routing)
要使用 OAuth 提供者進行使用者驗證,您需要兩個路由:一個用於將使用者導向 OAuth 提供者,另一個則用於在驗證完成後接收提供者的回呼。以下範例示範了這兩個路由的實作:
use Laravel\Socialite\Socialite;
Route::get('/auth/redirect', function () {
return Socialite::driver('github')->redirect();
});
Route::get('/auth/callback', function () {
$user = Socialite::driver('github')->user();
// $user->token
});
Socialite facade 所提供的 redirect 方法會處理將使用者導向 OAuth 提供者的流程;user 方法則會檢查進來的請求並在使用者同意授權後從提供者取得使用者資料。
驗證與儲存 (Authentication And Storage)
從 OAuth 提供者取得使用者資訊後,你可以檢查該使用者是否已存在於應用程式的資料庫中,並對使用者進行 驗證。若使用者尚未存在,通常會在資料庫中建立一筆新紀錄來表示該使用者:
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Laravel\Socialite\Socialite;
Route::get('/auth/callback', function () {
$githubUser = Socialite::driver('github')->user();
$user = User::updateOrCreate([
'github_id' => $githubUser->id,
], [
'name' => $githubUser->name,
'email' => $githubUser->email,
'github_token' => $githubUser->token,
'github_refresh_token' => $githubUser->refreshToken,
]);
Auth::login($user);
return redirect('/dashboard');
});
[!NOTE] 有關不同 OAuth 提供者所提供的使用者資訊詳情,請參閱「取得使用者資料」一節。
存取範圍 (Access Scopes)
在將使用者導向前,你可以使用 scopes 方法指定驗證請求中應包含的權限範圍(scopes)。此方法會將先前指定的 scopes 與新傳入的 scopes 合併:
use Laravel\Socialite\Socialite;
return Socialite::driver('github')
->scopes(['read:user', 'public_repo'])
->redirect();
若要覆寫驗證請求上的所有 scopes,可改用 setScopes 方法:
return Socialite::driver('github')
->setScopes(['read:user', 'public_repo'])
->redirect();
Slack Bot 權限範圍 (Slack Bot Scopes)
Slack 的 API 提供了不同類型的存取權杖(access tokens)(詳見 存取權杖類型),每種類型擁有其專屬的權限範圍。Socialite 相容於下列兩種 Slack 存取權杖類型:
- Bot (prefixed with
xoxb-) - User (prefixed with
xoxp-)
預設情況下,slack 驅動會產生 user 類型的權杖,呼叫該驅動的 user 方法會回傳使用者的詳細資料。
當您的應用程式需要向使用者所擁有的外部 Slack 工作區發送通知時,Bot 類型的權杖會很有用。若要產生 bot 權杖,請在將使用者導向 Slack 驗證前呼叫 asBotUser:
return Socialite::driver('slack')
->asBotUser()
->setScopes(['chat:write', 'chat:write.public', 'chat:write.customize'])
->redirect();
此外,在 Slack 驗證完成並將使用者導回應用程式後,您也必須在呼叫 user 方法之前先呼叫 asBotUser:
$user = Socialite::driver('slack')->asBotUser()->user();
當產生 bot 權杖時,user 方法仍會回傳 Laravel\Socialite\Two\User 實例;但只有 token 屬性會被填充。你可以將此 token 存起來,以便後續向已授權使用者的 Slack 工作區發送通知。
選用參數 (Optional Parameters)
許多 OAuth 提供者支援在導向請求中包含其他選用參數。要在請求中加入選用參數,可用一個關聯陣列呼叫 with 方法:
use Laravel\Socialite\Socialite;
return Socialite::driver('google')
->with(['hd' => 'example.com'])
->redirect();
[!WARNING] 使用
with方法時請注意不要傳入保留字,如state或response_type。
取得使用者資料 (Retrieving User Details)
在使用者被導回應用程式的驗證回呼路由後,可使用 Socialite 的 user 方法來取得使用者資料。user 方法回傳的物件包含多種屬性與方法,可用於擷取並儲存使用者在您資料庫中的相關資訊。
視所使用的 OAuth 提供者支援 OAuth 1.0 或 OAuth 2.0,不同的屬性與方法可能會存在於此物件上:
use Laravel\Socialite\Socialite;
Route::get('/auth/callback', function () {
$user = Socialite::driver('github')->user();
// OAuth 2.0 providers...
$token = $user->token;
$refreshToken = $user->refreshToken;
$expiresIn = $user->expiresIn;
// OAuth 1.0 providers...
$token = $user->token;
$tokenSecret = $user->tokenSecret;
// All providers...
$user->getId();
$user->getNickname();
$user->getName();
$user->getEmail();
$user->getAvatar();
});
從權杖取得使用者資料 (Retrieving User Details From A Token Oauth2)
如果您已經持有使用者的有效存取權杖(access token),可以使用 Socialite 的 userFromToken 方法來取得該使用者的資料:
use Laravel\Socialite\Socialite;
$user = Socialite::driver('github')->userFromToken($token);
若透過 iOS 應用使用 Facebook Limited Login,Facebook 可能會返回 OIDC token 而非一般的 access token。與 access token 一樣,可把 OIDC token 提供給 userFromToken 方法以取得使用者資料。
無狀態驗證 (Stateless Authentication)
stateless 方法可用來停用 session 狀態驗證。當在不使用 cookie 的無狀態 API 中加入社群驗證時,這個方法非常有用:
use Laravel\Socialite\Socialite;
return Socialite::driver('google')->stateless()->user();