Laravel Jetstreamでソーシャルログインを実装する

こんにちは。フリーランス・コンサルタント&エンジニアの 九保すこひ です。

さてさて、この間新しくリリースされたLaravel Jetstreamを使って「Laravel8.x以降でログイン機能をインストールする方法」という記事を公開しました。

Jetstreamは、ログインまわりに必要なものをほぼ全て用意してくれているので、デザインさえ変更すればそのままユーザー情報の設定ページとしては申し分ないと思います。

しかし、そんなJetstreamにもついていない機能があります。

それが・・・・・・

ソーシャルログイン機能

です。

ソーシャルログイン」というのは、例えばGoogleYahooLINEなどの登録済みデータを使って簡単にログインやユーザー登録ができるようになる機能のことです。

メリットとしては、以下のような「やーめた!」を減らすことができるというのが大きいんじゃないでしょうか。

  • 「メールアドレス&パスワードでログインするのめんどうだから、やーめた!」
  • 「登録しようと思ったけど入力ややっこしいな、やーめた!」

つまり、すでにGoogleなどにログイン済みならクリックだけでユーザー登録を完了できるというわけですね。

そこで❗

今回はLaravel JetstreamがインストールされたLaravel 8.xにソーシャルログインを実装してみたいと思います。

ぜひ皆さんのお役に立てましたら嬉しいです。😊✨
(最後にソースコード一式がダウンロードできますよ👍)

「(記事を書いた時点で)リリース1週間ですが、
すでにLaravelが8.2になってました😲」

開発環境: Laravel 8.x、Laravel Socialite 5

やりたいこと

最新バージョンのLaravel 8.1.0 + Laravel Socialite 5.0.0(2020.9.12現在)でLINEのソーシャルログインを実装します。

ちなみに、LINEのソーシャルログインは、social plusさんの調査によると一番人気だそうです。そして、Yahoo JapanFacebookと続くようですね。

前提として

Laravel 8.xからログインまわりの管理をすることになったパッケージLaravel Jetstreamがインストールされていることが前提です。

もしまだの方は以下のページを参考にして済ませておいてください。

📝 Laravel8.x以降でログイン機能をインストールする方法

LINEからソーシャルログインに必要な情報を取得する

アクセス情報を取得する

では、プログラムに入る前にソーシャルログインに必要となる情報を取得しておきましょう。

まず、LINE Developersにログインします。

ログインをすると、プロバイダーのリストが表示されているので(まだ登録していない場合は先に登録してから)好きなものをクリックします。

プロバイダーを選択すると、チャネルの画面になりますので「新規チャネル作成」をクリックしてください。

すると、チャネルの種類を聞かれますので、「LINEログイン」をクリック。

すると、チャネル登録フォームが表示されますので以下の内容を入力してください。(必須入力のものだけになりますが、アイコン画像なども登録できます)

  • チャネル名: 「Laravel 8:ソーシャルログイン」など
  • チャネル説明: 「Laravel Jetstreamを使ったソーシャル・ログインの実装」など
  • アプリタイプ: ウェブアプリを選択してください
  • メールアドレス: 何か連絡があるときに受け取るためのメールアドレス
  • LINE Developers Agreementへの同意(チェックボックス)

入力が完了したら「作成」ボタンをクリックしてください。

作成が完了したら、チャネルの基本情報が表示されますので、それぞれ「LINE_CLIENT_ID」と「LINE_CLIENT_SECRET」を取得し、.envへ書き込んでおきましょう。

書かれている場所は次のとおりです。

(LINE_CLIENT_ID)

(LINE_CLIENT_SECRET)

これらの情報を以下のように.envへ追加します。

LINE_CLIENT_ID=********************
LINE_CLIENT_SECRET=**********************************

コールバックURLを設定する

次に、LINEのソーシャルログイン・ページから帰ってくるURLを設定しておきましょう。

今回は、テスト環境ですので「http://l8x.test/login/line/callback」として設定します。

そして、このコールバックURLも先ほどと同様、.envへ追加しておきましょう。

LINE_CLIENT_ID=********************
LINE_CLIENT_SECRET=**********************************
LINE_REDIRECT_URI=http://l8x.test/login/line/callback

さらに、パッケージがこれらの情報にアクセスできるよう、コンフィグファイルの中にも同じく設定をしておきます。

config/services.php

<?php

return [

    // 省略

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

];

メールアドレス取得権限

実はLINEのソーシャル・ログインは初期状態ではメールアドレスが取得できません。(おそらくセキュリティ上の配慮かと思います)

そのため、メールアドレスを取得できるようにするために、申請をしておく必要があります。

場所は、LINE_CLIENT_IDなどを取得した「チャネル基本設定」ページの下部の「OpenID Connect」という項目になります。

初期状態では「未申請」となっていますので、「申請」ボタンをクリックしましょう。

すると、申請フォームが表示されるので、各チェックボックスにチェックを入れ、ちょっとめんどうですが、LINEの説明で以下のようにあるように必ずスクリーショットをとってアップロードしましょう。

(LINE Developerより引用)
あなたのアプリでメールアドレスの取得/利用目的について、ユーザに通知、明示、および同意を取得している部分のスクリーンショットをアップロードしてください。

ちなみに私の場合は以下のようなスクリーショットを使いました。

※この部分は後ほどビューを変更する部分でコードも紹介します。

パッケージをインストールする

Socialite本体をインストール

まずはSocialiteのパッケージ本体をインストールします。
以下のコマンドを実行してください。

composer require laravel/socialite

LINE用のパッケージをインストール

続いて、LINEでのソーシャルログインを実装するために以下のプロバイダー・パッケージもインストールしてください。

composer require socialiteproviders/line

インストールが完了したら、Laravel側にLINEプロバイダーが使えるように設定をします。

app/Providers/EventServiceProvider.php

// 省略

protected $listen = [
    Registered::class => [
        SendEmailVerificationNotification::class,
    ],
    // 👇 ここに追加
    \SocialiteProviders\Manager\SocialiteWasCalled::class => [
        'SocialiteProviders\\Line\\LineExtendSocialite@handle',
    ],
];

// 省略

つまり、今回はLINEだけですので、ひとつだけですが、今後FacebookGitHubのパッケージをインストールした場合は、同じようにして追加する必要があります。

ルートをつくる

では、今後別のソーシャル・ログインが追加になることも想定して可変のルートをつくっておくことにします。

routes/web.php

// ソーシャル・ログイン
Route::prefix('login/{provider}')->where(['provider' => '(line|github)'])->group(function(){

    Route::get('/', 'App\Http\Controllers\Auth\LoginController@redirectToProvider')->name('social_login.redirect');
    Route::get('/callback', 'App\Http\Controllers\Auth\LoginController@handleProviderCallback')->name('social_login.callback');

});

ここで重要なのがwhere()の部分です。

ここでは、login/{provider}に入ってくるパラメータを正規表現を使って制限しています。

つまり、上の例で有効になるURLは以下の4つです。

  • /login/line
  • /login/line/callback
  • /login/github
  • /login/github/callback

※ 例でわかりやすいようにgithubも追加していますが、実際には今回は不要です。

コントローラーをつくる

実は、これまでのLaravelではログイン機能をインストールすると「app/Http/Controllers/Auth/LoginController.php」というファイルが存在していました。

しかし、Laravel 8.xからはJetstreamを使うようになり、このファイルが不要になってしまったので、以下のコマンドで作成する必要があります。

php artisan make:controller Auth\\LoginController

実行すると、ファイルが作成されますので中身を以下のようにします。

app/Http/Controllers/Auth/LoginController.php

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Laravel\Socialite\Facades\Socialite;

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;
        $social_user = Socialite::driver($provider)->user();
        $social_email = $social_user->getEmail();
        $social_name = $social_user->getName();

        if(!is_null($social_email)) {

            $user = User::firstOrCreate([
                'email' => $social_email
            ], [
                'email' => $social_email,
                'name' => $social_name,
                'password' => Hash::make(Str::random())
            ]);

            auth()->login($user);
            return redirect('/dashboard');

        }

        return '必要な情報が取得できていません。';

    }
}

この中でやっていることは次のとおりです。

redirectToProvider()

ソーシャルログインをするページ(今回ならLINEのページ)へリダイレクトするメソッドです。このメソッドが自動的に必要なパラメーターをつけてくれます。

handleProviderCallback()

各ソーシャル・ログインから帰ってくるページです。

この中では、メールアドレスを使って、以下の内容を実行しています。

  • すでに登録されていればそのままログイン
  • 登録されていなければ新規ユーザー登録してログイン

なお、以下の部分はルートで設定した「可変部分」で、この中に例えば、「line」や「github」、「facebook」などの文字列が入ってくることになります。

$provider = $request->provider;

ご注意: ただし、チーム機能を有効にしている場合、最低でもひとつはチームに所属しておく必要がありますので注意してください。詳しくは、以下のページをご覧ください。

📝 新しいFactoryでテストユーザーをつくってログインしてみる

ビューにソーシャル・ログインを追加する

続いて、ログインページにソーシャルログインへのリンクを作成しましょう。(LINEの場合は、この変更後にスクリーショットをとって申請をする必要があります)

以下のファイルを変更してください。

resources/views/auth/login.blade.php

<!-- 省略 -->

    <!-- 👇 ここが最初から存在しているログインボタン -->

    <x-jet-button class="ml-4">
        {{ __('Login') }}
    </x-jet-button>
</div>

<!-- 👇 このブロックを追加 -->
<hr class="my-3">
<div class="mt-3">
    <h3>ソーシャル・ログイン</h3>
    <div class="my-2">
        <a href="{{ route('social_login.redirect', 'line') }}">
            <img style="height:50px" src="/images/LINE_APP.png">
        </a>
    </div>
    <small>
        本ウェブサービスでは、LINEによる認証ページで許可を得た場合のみメールアドレスを取得します。<br>
        そして、取得されたメールアドレスにつきましては本サービスのログイン以外の目的には一切使用しません。
    </small>
</div>

<!-- 省略 -->

なお、LINEのロゴは以下のページでダウンロードできます。

📝 LINEのロゴ・ダウンロードページ

テストしてみる

では、実際にテストしてみましょう❗

まず現在のところusersテーブルには何もデータが入っていません。

この状態で「http://******/login」にアクセスします。

すると、以下のようなフォームが表示されるのでLINEアイコンをクリックしてみます。

LINEが用意してくれているソーシャルログイン・ページが表示されました。

メールアドレス&パスワード、もしくはLINEアプリでQRコードを読み取ってログインしてください。

ログインすると、自動的にリダイレクトして・・・・・・

はい!Laravelに戻ってきました。
うまくログインもできています。

ではusersテーブルも確認しておきましょう。

ソーシャルログインのユーザーで新しいデータが追加されています。
お疲れ様でした😊✨

ちなみに

ちなみに、今回のコードは「メールアドレス単位」での実装になります。そのため、もしLINEGitHubの方でメールアドレスを変更されてしまった場合は、それまでのユーザーではログインできなくなってしまします。

詳しくは、過去記事「Laravel / Socialite で気をつけるべき事のまとめ」をご覧ください。(もしくは専用のsocial_usersなどのテーブルを作って複数サイトにも対応できるようにするのもアリかもですね)

ダウンロードする

今回実際に開発したソースコード一式を以下からダウンロードすることができます。

Laravel Jetstreamでソーシャルログインを実装する

※ ただし、Jetstreamのインストールや.envなど各種IDのセットはご自身で行っていただく必要があります。

開発のご依頼お待ちしております
開発のご依頼はこちらから: お問い合わせ
どうぞよろしくお願いいたします! by 九保すこひ

おわりに

ということで、今回はLarave 8.xにソーシャルログイン機能をつける方法をご紹介しました。

基本的な流れはこれまでのLaravelと同じですが、LoginControllerが存在していなかったりするので、一見「おや??」と思う部分もあるかと思います。

あとは、途中でも書きましたがLINEのソーシャルログインが初期状態ではメールアドレスを提供してくれない、というのも落とし穴といえば落とし穴かもしれません。(たしかツイッターもそうでしたよね??)

今回はこんなところで終了です。
ぜひみなさんもチャレンジしてみてくださいね。

ではでは〜❗

「四季が『二季』化してきて、
すぐ体が気温に対応できないです💦」

このエントリーをはてなブックマークに追加       follow us in feedly