11
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Laravel】JetstreamでSNS認証(ソーシャルログイン)

Last updated at Posted at 2020-11-16
  • Laravel8でのソーシャルログインの実装メモ。

Laravel Socialite(ソーシャライト)

実装

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
11
13
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?