- Laravel8でのソーシャルログインの実装メモ。
Laravel Socialite(ソーシャライト)
- OAuth認証のパッケージ。
- Facebook、Twitter、Google、GitHub、Instagram、YouTube、LINE、Slackなどに対応。
- Laravel Socialite(GitHub)
- Laravelのドキュメント
- Socialite Providers(※ Socialite 4.x は、PHP >= 7.1.3、 Laravel5.6 以上で!)
実装
0. インストール
インストール
% composer require laravel/socialite // socialite
// 例) 各メディア用もインストール ↓
% composer require socialiteproviders/twitter // Twitter
% composer require socialiteproviders/line // LINE
% composer require socialiteproviders/facebook // Facebook
% composer require socialiteproviders/google // Google
% composer require socialiteproviders/yahoo // Yahoo
(エラー)インストールできない。。
Your requirements could not be resolved to an installable set of packages.
% composer update // バージョンエラーだったので、アップデートし、再度インストールで解決。
1. ソーシャルメディア側でやること
- id と シークレットの取得。
- コールバックURLの設定(アプリ側に返すURLを指定)。
- ローカルなら、http://localhost:8000/login/twitter/callback とか。
2. アプリ側でやること
2-1. id、シークレット、コールバックするURL を設定
環境変数で呼び出して使えるように設定
// .env
TWITTER_KEY="xxxxxxxxxx"
TWITTER_SECRET="xxxxxxxxxx"
TWITTER_REDIRECT_URI="http://localhost:8000/login/twitter/callback"
:
// config/services.php
'twitter' => [
'client_id' => env('TWITTER_KEY'),
'client_secret' => env('TWITTER_SECRET'),
'redirect' => env('TWITTER_REDIRECT_URI'),
],
:
2-2. ルーティング
- 各ソーシャルメディアごとに、「/login/twitter、 /login/twitter/callback」って感じでルートを作成。
- アプリ → ソーシャルメディアに送ってログインするルート と、 ログイン後に返ってくるルート。
routes/web.php
Route::prefix('login/{provider}')->where(['provider' => '(line|twitter|facebook|google|yahoo)'])->group(function(){
Route::get('/', [App\Http\Controllers\LoginController::class, 'redirectToProvider'])->name('sns_login.redirect');
Route::get('/callback', [App\Http\Controllers\LoginController::class, 'handleProviderCallback'])->name('sns_login.callback');
});
2-3. プロバイダ
① ソーシャルメディアが使えるよーに、プロバイダを登録(config/app.php)。
② イベントリスナーを作成(Eventサービスプロバイダ)。
プロバイダの作成と登録
// ① プロバイダの登録(config/app.php)
'providers' => [
\SocialiteProviders\Manager\ServiceProvider::class, // 追加
],
// ② イベントリスナーの作成(app/Providers/Eventサービスプロバイダ)
use SocialiteProviders\Manager\SocialiteWasCalled;
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
// 追加 ↓
\SocialiteProviders\Manager\SocialiteWasCalled::class => [
'SocialiteProviders\\Line\\LineExtendSocialite@handle',
'SocialiteProviders\\Twitter\\TwitterExtendSocialite@handle',
'SocialiteProviders\\Facebook\\FacebookExtendSocialite@handle',
'SocialiteProviders\\Google\\GoogleExtendSocialite@handle',
'SocialiteProviders\\Yahoo\\YahooExtendSocialite@handle',
:
],
];
2-4. コントローラー
- Laravel7.xまでは、ログイン関連はLoginコントローラが担当だったらしいけど、Laravel8(Jetstream)では、不要になり、デフォルトでは作成されない。なので、作成。
Loginコントローラの作成
% php artisan make:controller Auth\\LoginController
// app/Http/Controllers/Auth/LoginController.php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Laravel\Socialite\Facades\Socialite;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
class LoginController extends Controller {
// メディア側へのリダイレクト
public function redirectToProvider(Request $request) {
$provider = $request->provider;
return Socialite::driver($provider)->redirect();
}
// メディア側から返されるユーザー情報
public function handleProviderCallback(Request $request) {
$provider = $request->provider;
$sns_user = Socialite::driver($provider)->user();
$sns_email = $sns_user->getEmail();
$sns_name = $sns_user->getName();
// 登録済ならログイン。未登録ならアカウント登録してログイン
if(!is_null($sns_email)) {
$user = User::firstOrCreate( // Userモデルに、レコードがあれば取得、なければ保存
[ 'email' => $sns_email ],
[ 'email' => $sns_email, 'name' => $sns_name, 'password' => Hash::make(Str::random())
]);
auth()->login($user);
session()->flash('oauth_login', $provider.'でログインしました。');
return redirect('/');
}
return '情報が取得できませんでした。';
}
}
-
redirectToProvider
: OAuth側へのリダイレクト。 -
handleProviderCallback
: OAuth認証後に返ってきた情報の処理(ユーザー情報の取得)。
2-5. ビュー
- ログイン画面にソーシャルログインボタンを設置。
resources/views/auth/login.blade.php
<div>
<a href="{{ route('sns_login.redirect', 'twitter') }}">Twitter</a>
</div>
例) ユーザー情報の取得方法
- SNS認証でログイン後に、返されるユーザー情報の取得方法のイロイロ。
参)ユーザー情報の取得方法
$provider = $request->provider;
$user = Socialite::driver($provider)->user(); // ユーザー情報全部の取得
$user->getId(); // id
$user->getNickname(); // @xxxxの部分とか
$user->getName(); // 名前
$user->getEmail(); // メールアドレス
$user->getAvatar(); // アバターの画像のURL
$user->accessTokenResponseBody; // トークン( Array([oauth_token]=>xxxxx, [oauth_token_secret]=>xxxxx, [user_id] =>xxxxx, [screen_name]=>xxxxx ) )
参) エラー時のメモ
ユーザー情報が格納できてるか?を確認してみる(コントローラー)
:
$sns_user = Socialite::driver($provider)->user();
dd($sns_user); // $sns_userの中身を確認
キャッシュクリアしてみる
% php artisan config:clear