6
3

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 1 year has passed since last update.

【Jetstream】Laravel8 SocialiteでLINEログイン機能を実装してみる

Last updated at Posted at 2022-08-31

Laravel Socialite

20220830_140454_2.jpg

・OAuth認証で俗にいうログインパッケージ。
・LINE、Facebook、Twitter、Google、GitHub、Instagram、等に対応。

仕事でちょっと使う機会があり各サイトのDeveloperへの登録の仕方も含めて
使い方を備忘録的に書いていきたいと思います。

基本的にSNS側のDeveloperサイトでは下記を設定。(名称はSNS毎に微妙に異なる)

・チャネルID
・チャネルシークレット
・コールバックURL

上記3点をlarvelの .envファイルに記載して使うイメージ。

【各SNS Developer側から返ってくるユーザ情報一覧】

laravel-socialite-returnユーザ情報.xlsx - Excel 2022-08.png

これを見ると下記3つのユーザ情報が上記6つのSNSでは返って来るようです。
SNSによってname or nickname だけ返って来るといった感じでしょうか。

id
email
avatar

※Facebook 、Githubは下記サイトの「Returned User fields」が未記載だったので
dd($user) で確認。

~ 2021年 ソーシャルログイン動向 ~

・2021年最も利用ユーザー数が多かったのはLINEログイン(76%)
・6種実装サイトでの利用ユーザー数は、1位がLINEログインで32%、2位がYahoo! JAPANログインで30%
・デバイス別ではスマートフォンでの利用が9割以上で、2019年比での伸び率は197%

2021年1月~2021年12月のソーシャルログイン利用状況222.png

何だかんだで利用ユーザ数の多い
LINEをソーシャルログインで実装すれば間違いはなさそうです。

ソーシャルログイン利用状況調査2021
https://socialplus.jp/report/2021

【環境】

・Windows11 pro
・laravel ^8.75
・php": "^7.3
・laravel/jetstream: "2.1
・laravel/socialite : ^5.0

【前提条件】

・laravel、jetstream設定が終わり起動済。
・composer をインストール済。

【SNS側のDeveloperサイトでの設定】

今回は developers.LINE の設定をメインに記載します。
(他のSNS側のdevelopersの設定は時間があれば書きたいと思います。)
※LINE / Twitter / Facebook はTel登録の必要あり

LINE Developers1.png
プロバイダーを作成ボタン
LINE Developers — プロバイダーを作成ボタン.png
「プロバイダー名」を入力して作成ボタン

LINE Developers — LINEログイン」を選択.png
「LINEログイン」を選択

LINE Developers — Mozilla Firefox 2022-09-01 12.46.png

・チャネルの種類 → 「LINEログイン」

・プロバイダー → そのまま

・サービスを提供する地域   →「日本」
・会社・事業者の所在国・地域 →「日本」

LINE Developers — Mozilla Firefox 2022-09-01 12.48.png

・チャネルアイコン →任意の画像を入力
・チャネル名 →任意の値を入力
・チャネル説明 →任意の値を入力

LINE Developers — Mozilla Firefox 2022-09-01 12.50.png

・アプリタイプ  → 「ウェブアプリ」を入力
・メールアドレス → 任意の値を入力

LINE Developers — Mozilla Firefox 2022-09-01 12.52.png
・公開ステータス  → 「開発」→ 「公開済」
・コールバックURL  → laravelのenvファイルと同じコールバックURLを入力。

LINE Developers7.png
・チャネルシークレット → laravelのenvファイルにコピペ。

LINE Developers — OpenID Connect メールアドレス取得権限.png
・OpenID Connect メールアドレス取得権限 → 申請ボタン押下

LINE Developers — メールアドレス取得権限2.png
・チェックを入れて、画面のスクリーンショットを取って、その画像をアップロード

LINE Developers — ステータスが「申請済み」に.png
・ステータスが「申請済み」に

LINE Developersの設定はこれで完了。

■ 他のSNS側のdeveloper (アカウント作成済である事)
設定はLINEのとさほど変わらないので適当にやれば出来るはず。。

Google cloud
developer.twitter
developer.github
developers.facebook
developers.yahoo

ngrokを使ってlocalhostを公開サーバのように出来るツール

ngrokの使い方(windows版)
https://qiita.com/backstreet/items/b21ce6439ef48d223ddf

localhostで動いているシステムを、
公開サーバ上のようにアクセスできるツールです。

ここで設定した公開用URLを
各SNSのdeveloper側でコールバックurlとして設定すると便利です。

コールバックurlを「localhost」で設定するとうまく動作しないものがあるのでこっちのほうが良いかも

【Laravel側での設定】

Githubに作業ソースを上げています
laravel Socialite 、各メディアのプロバイダーをインストール
composer require laravel/socialite

composer require socialiteproviders/line
composer require socialiteproviders/twitter
composer require socialiteproviders/yahoo
composer require socialiteproviders/google
composer require socialiteproviders/facebook
チャネルID、チャネルシークレット、コールバックURL の設定
.env
LINE_CHANNEL_ID=XXXXXXXXXXXXXX
LINE_CHANNEL_SECRET=XXXXXXXXXXXXXX
LINE_REDIRECT='https://XXXXXXXXXXXXXX/login/line/callback'
config/services.php
'line' => [
    'client_id'     =>env('LINE_CHANNEL_ID'),
    'client_secret' =>env('LINE_CHANNEL_SECRET'),
    'redirect'      =>env('LINE_REDIRECT'),
],
ルーティングの設定
routes/web.php
Route::prefix('login/{provider}')->where(['provider' => '(line|google|twitter|facebook|yahoo|github)'])->group(function(){
    Route::get('/',         [LoginController::class, 'redirectToProvider']);
    Route::get('/callback', [LoginController::class, 'handleProviderCallback']);
});

/login/line
→LINE Developersにサーバ情報を下さいリダイレクト

/login/line/callback
→LINE Developersから送られてくるサーバ情報を受け取る

プロバイダの設定
config/app.php
'providers' => [
    \SocialiteProviders\Manager\ServiceProvider::class,   // 追加
],

'aliases' => [
        'Socialite' => Laravel\Socialite\Facades\Socialite::class,  // 追加
app\Providers\EventServiceProvider.php
    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',
        
        ],
        //追加 ここまで

    ];
    
    
ユーザーテーブルに各SNSのidを保存するカラムを追加

migrationファイル作成

php artisan make:migration add_sns_id_to_users_table

下記のように編集

database\migrations\2022_08_26_021730_add_sns_id_to_users_table.php
<?php


use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;


class AddSocialiteIdToUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table("users", function (Blueprint $table) {
            // 追加
            $table->string("provider")->after('password')->nullable();
            $table->string("line_id")->after('provider')->nullable();
            $table->string("google_id")->after('line_id')->nullable();
            $table->string("facebook_id")->after('google_id')->nullable();
            $table->string("yahoo_id")->after('facebook_id')->nullable();
            $table->string("twitter_id")->after('yahoo_id')->nullable();
            $table->string("github_id")->after('twitter_id')->nullable();
        });
    }


    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table("users", function (Blueprint $table) {
            // 追加
            $table->dropColumn('provider'); //SNS判別用
            $table->dropColumn('line_id');
            $table->dropColumn('google_id');
            $table->dropColumn('facebook_id');
            $table->dropColumn('yahoo_id');
            $table->dropColumn('twitter_id');
            $table->dropColumn('github_id');
        });
    }
}

マイグレーション

php artisan migrate
Userモデルのホワイトリストに追加したSNSのカラムを追加
app\Models\User.php
    protected $fillable = [
        'name',
        'email',
        'password',
        'provider',
        "line_id",
        "google_id",
        "facebook_id",
        "yahoo_id",
        "twitter_id",
        "github_id",
    ];
Loginコントローラの作成の設定

Laravel8からはログイン関連は
Loginコントローラはなくなったので新しく作成。

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 Laravel\Socialite\Facades\Socialite;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller {

    // SNSのOAuth側へリダイレクト
    public function redirectToProvider(Request $request) {
        $provider = $request->provider;
     //   dd($provider);

        return Socialite::driver($provider)->redirect();
    }

    // SNS側からcallbackされるユーザー情報
    public function handleProviderCallback(Request $request) {
        try {
            $provider = $request->provider;
            $sns_user = Socialite::driver($provider)->user();
        //    dd($sns_user);

            $sns_email = '';
            $sns_name = '';
            $sns_nickname = '';

            //各SNSのID
            $line_id = '';
            $google_id = '';
            $facebook_id = '';
            $yahoo_id = '';
            $twitter_id = '';
            $github_id = '';

            $sns_email = $sns_user->getEmail();
            $sns_name  = $sns_user->getName();
            $sns_nickname  = $sns_user->getNickname();
            if(!$sns_name){ $sns_name = $sns_nickname;} // github用の処理 (nicknameしかないので)
        //    dd($provider);
        //    dd($sns_email);


            if($provider == 'line'){
                $line_id = $sns_user->getId();
            }elseif($provider == 'google'){
                $google_id = $sns_user->getId();
            }elseif($provider == 'twitter'){
                $twitter_id = $sns_user->getId();
            }elseif($provider == 'github'){
                $github_id = $sns_user->getId();
            }elseif($provider == 'facebook'){
                $facebook_id = $sns_user->getId();
            }elseif($provider == 'yahoo'){
                $yahoo_id = $sns_user->getId();
            }

            $provider_culmn='';
            $provider_culmn = $provider . "_id";


            //  $user = Socialite::driver("google")->user();
                $finduser = User::where($provider_culmn, $sns_user->getId())->first();

                if ($finduser) {
                    Auth::login($finduser);
                    return redirect()->intended("dashboard");
                } else {
                    $newUser = User::create([
                        'email'    => $sns_email, 
                        'name'     => $sns_name, 
                        'provider' => $provider, 
                        'line_id'  => $line_id,
                        'google_id'  => $google_id,
                        'yahoo_id'  => $yahoo_id,
                        'twitter_id'  => $twitter_id,
                        'github_id'  => $github_id,
                        'facebook_id'  => $facebook_id,
                        'password' => Hash::make(Str::random())
                    ]);

                    Auth::login($newUser);

                    return redirect()->intended("dashboard");
                }
            } catch (Exception $e) {
                \Log::error($e);
                throw $e->getMessage();
            }
 
    }
}

ログイン画面にソーシャルログインボタンを設定 (Jetstream Inertia.jsなのでvueです)
resources\js\Pages\Auth\Login.vue
<div class="flex items-center">
    <jet-button class="ml-0 bg-green-500 w-80">
        <a href="login/line">
            Login with LINE
        </a>
    </jet-button>
</div>
LINEでログインしてみると

login1.png

LINEログイン画面にリダイレクト
login2.png

dashboard画面に切り替わり、右上に名前が表示されています。
login3.png

phpmyadminの中を確認してみると、、
login4.png

どうやらLINEログイン出来たようです。

SNS認証後に、返されるユーザー情報。
$user = Socialite::driver($provider)->user();    // Email
dd($user);

$user->getId();      // ID  (各SNSのユーザ固有のID)
$user->getNickname();   // 名前 (github等の名前で使われている)
$user->getName();       // 名前
$user->getEmail();      // Email
$user->getAvatar();     // プロフィール画像のURL

【備考】

docker上では何故かLINEとの連携が出来なかったので
通常のlocalhostで起動。

Windows上だと連携が出来ない等の報告があるようです。
何か情報をお持ちの人いれば教えてください。

https://teratail.com/questions/285618
https://biz.addisteria.com/laravel_line_integration/

ありがとうございました。
誤字・記載ミス等ありましたらメッセージ下さい。

6
3
0

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
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?