Laravel Socialite
簡介
除了傳統的基於表單的身份驗證外,Laravel 還提供了一種簡單、便捷的方法,透過 Laravel Socialite 使用 OAuth 提供商進行身份驗證。Socialite 目前支援透過 Facebook、X、LinkedIn、Google、GitHub、GitLab、Bitbucket 和 Slack 進行身份驗證。
其他平臺的介面卡可透過社群驅動的 Socialite Providers 網站獲取。
安裝
要開始使用 Socialite,請使用 Composer 包管理器將該包新增到專案的依賴項中
1composer require laravel/socialite
升級 Socialite
升級到 Socialite 的新主版本時,請務必仔細閱讀 升級指南。
配置
在使用 Socialite 之前,您需要為您應用所使用的 OAuth 提供商新增憑據。通常,這些憑據可以透過在您要進行身份驗證的服務儀表板中建立“開發者應用”來獲取。
這些憑據應放置在您應用的 config/services.php 配置檔案中,並根據您的應用所需的提供商,使用 facebook、x、linkedin-openid、google、github、gitlab、bitbucket、slack 或 slack-openid 作為鍵。
1'github' => [2 'client_id' => env('GITHUB_CLIENT_ID'),3 'client_secret' => env('GITHUB_CLIENT_SECRET'),4 'redirect' => 'http://example.com/callback-url',5],
如果 redirect 選項包含相對路徑,它將自動解析為完全限定的 URL。
認證
路由
要使用 OAuth 提供商驗證使用者身份,您需要兩條路由:一條用於將使用者重定向到 OAuth 提供商,另一條用於在身份驗證後接收來自提供商的回撥。下面的示例路由演示了這兩條路由的實現
1use Laravel\Socialite\Socialite; 2 3Route::get('/auth/redirect', function () { 4 return Socialite::driver('github')->redirect(); 5}); 6 7Route::get('/auth/callback', function () { 8 $user = Socialite::driver('github')->user(); 9 10 // $user->token11});
Socialite 門面提供的 redirect 方法負責將使用者重定向到 OAuth 提供商,而 user 方法則會檢查傳入的請求,並在使用者批准身份驗證請求後從提供商處檢索使用者資訊。
身份驗證與儲存
從 OAuth 提供商獲取使用者資訊後,您可以確定該使用者是否存在於您的應用資料庫中並 對使用者進行身份驗證。如果該使用者不存在於您的資料庫中,您通常會在資料庫中建立一個新記錄來代表該使用者。
1use App\Models\User; 2use Illuminate\Support\Facades\Auth; 3use Laravel\Socialite\Socialite; 4 5Route::get('/auth/callback', function () { 6 $githubUser = Socialite::driver('github')->user(); 7 8 $user = User::updateOrCreate([ 9 'github_id' => $githubUser->id,10 ], [11 'name' => $githubUser->name,12 'email' => $githubUser->email,13 'github_token' => $githubUser->token,14 'github_refresh_token' => $githubUser->refreshToken,15 ]);16 17 Auth::login($user);18 19 return redirect('/dashboard');20});
有關特定 OAuth 提供商可提供哪些使用者資訊的更多資訊,請參閱 獲取使用者詳細資訊 的文件。
訪問範圍 (Access Scopes)
在重定向使用者之前,您可以使用 scopes 方法來指定身份驗證請求中應包含的“作用域 (scopes)”。此方法會將之前指定的所有作用域與您當前指定的作用域合併。
1use Laravel\Socialite\Socialite;2 3return Socialite::driver('github')4 ->scopes(['read:user', 'public_repo'])5 ->redirect();
您可以使用 setScopes 方法覆蓋身份驗證請求上所有現有的作用域。
1return Socialite::driver('github')2 ->setScopes(['read:user', 'public_repo'])3 ->redirect();
Slack 機器人作用域
Slack 的 API 提供了 不同型別的訪問令牌,每種都有其對應的 許可權作用域。Socialite 相容以下兩種 Slack 訪問令牌型別:
- Bot(字首為
xoxb-) - User(字首為
xoxp-)
預設情況下,slack 驅動程式將生成一個 user 令牌,呼叫驅動程式的 user 方法將返回使用者的詳細資訊。
如果您希望應用向由應用使用者擁有的外部 Slack 工作區傳送通知,Bot 令牌非常有用。要生成 Bot 令牌,請在將使用者重定向到 Slack 進行身份驗證之前呼叫 asBotUser 方法。
1return Socialite::driver('slack')2 ->asBotUser()3 ->setScopes(['chat:write', 'chat:write.public', 'chat:write.customize'])4 ->redirect();
此外,在 Slack 將使用者重定向回您的應用進行身份驗證後,您必須在呼叫 user 方法之前呼叫 asBotUser 方法。
1$user = Socialite::driver('slack')->asBotUser()->user();
生成 Bot 令牌時,user 方法仍會返回 Laravel\Socialite\Two\User 例項;但是,只有 token 屬性會被填充。此令牌可以儲存起來,以便 向已驗證使用者的 Slack 工作區傳送通知。
可選引數
許多 OAuth 提供商支援重定向請求中的其他可選引數。要在請求中包含任何可選引數,請使用關聯陣列呼叫 with 方法。
1use Laravel\Socialite\Socialite;2 3return Socialite::driver('google')4 ->with(['hd' => 'example.com'])5 ->redirect();
使用 with 方法時,請注意不要傳遞任何保留關鍵字,例如 state 或 response_type。
獲取使用者詳細資訊
在使用者被重定向回您的應用身份驗證回撥路由後,您可以使用 Socialite 的 user 方法檢索使用者的詳細資訊。user 方法返回的使用者物件提供了多種屬性和方法,您可以使用它們將使用者資訊儲存在自己的資料庫中。
根據您進行身份驗證的 OAuth 提供商是否支援 OAuth 1.0 或 OAuth 2.0,此物件上可能提供不同的屬性和方法。
1use Laravel\Socialite\Socialite; 2 3Route::get('/auth/callback', function () { 4 $user = Socialite::driver('github')->user(); 5 6 // OAuth 2.0 providers... 7 $token = $user->token; 8 $refreshToken = $user->refreshToken; 9 $expiresIn = $user->expiresIn;10 11 // OAuth 1.0 providers...12 $token = $user->token;13 $tokenSecret = $user->tokenSecret;14 15 // All providers...16 $user->getId();17 $user->getNickname();18 $user->getName();19 $user->getEmail();20 $user->getAvatar();21});
從令牌獲取使用者詳細資訊
如果您已經擁有使用者的有效訪問令牌,則可以使用 Socialite 的 userFromToken 方法獲取他們的使用者詳細資訊。
1use Laravel\Socialite\Socialite;2 3$user = Socialite::driver('github')->userFromToken($token);
如果您透過 iOS 應用使用 Facebook Limited Login,Facebook 將返回 OIDC 令牌而不是訪問令牌。與訪問令牌一樣,OIDC 令牌可以提供給 userFromToken 方法以獲取使用者詳細資訊。
無狀態身份驗證 (Stateless Authentication)
stateless 方法可用於停用會話狀態驗證。這在將社交登入功能新增到不使用基於 Cookie 會話的無狀態 API 時非常有用。
1use Laravel\Socialite\Socialite;2 3return Socialite::driver('google')->stateless()->user();
測試
Laravel Socialite 提供了一種便捷的方法來測試 OAuth 身份驗證流程,而無需向 OAuth 提供商發出實際請求。fake 方法允許您模擬 OAuth 提供商的行為並定義應返回的使用者資料。
模擬重定向
要測試您的應用是否正確地將使用者重定向到 OAuth 提供商,您可以在請求重定向路由之前呼叫 fake 方法。這將導致 Socialite 返回一個指向模擬授權 URL 的重定向,而不是重定向到實際的 OAuth 提供商。
1use Laravel\Socialite\Socialite;2 3test('user is redirected to github', function () {4 Socialite::fake('github');5 6 $response = $this->get('/auth/github/redirect');7 8 $response->assertRedirect();9});
模擬回撥
要測試應用的重定向回撥路由,您可以呼叫 fake 方法並提供一個 User 例項,該例項將在應用請求從提供商處獲取使用者詳細資訊時返回。User 例項可以使用 map 方法建立。
1use Laravel\Socialite\Socialite; 2use Laravel\Socialite\Two\User; 3 4test('user can login with github', function () { 5 Socialite::fake('github', (new User)->map([ 6 'id' => 'github-123', 7 'name' => 'Jason Beggs', 9 ]));10 11 $response = $this->get('/auth/github/callback');12 13 $response->assertRedirect('/dashboard');14 15 $this->assertDatabaseHas('users', [16 'name' => 'Jason Beggs',18 'github_id' => 'github-123',19 ]);20});
預設情況下,User 例項還將包含一個 token 屬性。如果需要,您可以手動在 User 例項上指定其他屬性。
1$fakeUser = (new User)->map([2 'id' => 'github-123',3 'name' => 'Jason Beggs',5])->setToken('fake-token')6 ->setRefreshToken('fake-refresh-token')7 ->setExpiresIn(3600)8 ->setApprovedScopes(['read', 'write'])