25
16

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.

Laravel8でLINEログインを実装する

Posted at

はじめに

Laravel8でLINEログインの実装を行ったので備忘録として残しておきます。

環境

PHP 7.4.27
Laravel 8.78.1

#事前準備
LINEログインの機能を使用するにはLINE Developersコンソールでプロバイダー及びLINEログインのチャネルを作成しておく必要があります。

下記のドキュメントを参考に作成していきますが詳細は割愛します。

チャネルを作成することでチャネルID、チャネルシークレットを取得できます。
コールバックURLも忘れずに設定しておきましょう。

#実装
LINEログインの実装部分に焦点を当てているためLaravelプロジェクトの作成や通常のログインなどの認証関連のパッケージの導入は省略しています。

Laravel Socialiteをインストール

今回はLaravelの公式パッケージであるLaravel Socialiteを使用して実装していきます。
Socialiteを使用することで外部サービスのアカウントによるログイン機能をよりシンプルに実装できます。

下記のコマンドを実行してSocialiteをインストールします。

composer require laravel/socialite

公式パッケージがサポートしている外部サービスにLINEが含まれていないので下記サイトで別途プロバイダーの追加方法を確認します。

LINEプロバイダーを追加するには下記のコマンドを実行します。

composer require socialiteproviders/line

環境変数の設定

事前準備で取得したチャネルID、チャネルシークレットと設定したコールバックURLを.envファイルに設定します。

LINE_CLIENT_ID='取得したチャネルID'
LINE_CLIENT_SECRET='取得したチャネルシークレット'
LINE_REDIRECT_URI='(アプリのURL)/login/line/callback'

configで設定しておきます。

config/services.php
'line' => [    
    'client_id' => env('LINE_CLIENT_ID'),  
    'client_secret' => env('LINE_CLIENT_SECRET'),  
    'redirect' => env('LINE_REDIRECT_URI') 
],

イベントを追加

Socialiteに別途プロバイダーを追加している場合はapp/Providers/EventServiceProviderへ追加の記述をします。
Laravel8からは記述方法が変わっています。

app/Providers/EventServiceProvider.php
protected $listen = [
    // 下記3行を追加
    \SocialiteProviders\Manager\SocialiteWasCalled::class => [
        \SocialiteProviders\Line\LineExtendSocialite::class.'@handle',
    ],
];

usersテーブルの変更

LINEログインしたユーザーから取得したプロバイダーIDを保存するためにusersテーブルを変更します。
メールアドレスによるログイン方法も残すにはemailpasswordでnullを許容しておきます。

database/migrations/2014_10_12_000000_create_users_table.php
public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('email')->unique()->nullable(); // 変更
        $table->timestamp('email_verified_at')->nullable();
        $table->string('password')->nullable(); // 変更
        $table->string('line_user_id')->unique()->nullable(); // 追加
        $table->rememberToken();
        $table->timestamps();
    });
}

変更したらマイグレーションを実行してテーブルを作成しておきましょう。

php artisan migrate

Userモデルの変更

usersテーブルを変更したのでUserモデルもあわせて変更します。

app/Models/User.php
<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var string[]
     */
    protected $fillable = [
        'name',
        'email',
        'password',
        'line_user_id' // 追加
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'line_user_id' // 追加
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

ルーティングを追加

次にLINEログインに関わる処理のルーティングを追加します。
認証関連のパッケージを導入したときにログイン用のコントローラーが作成されているので利用します。

routes/web.php
<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Auth\LoginController;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Auth::routes();
Route::prefix('login')->name('login.')->group(function() {
    Route::get('/line/redirect', [LoginController::class, 'redirectToProvider'])->name('line.redirect');
    Route::get('/line/callback', [LoginController::class, 'handleProviderCallback'])->name('line.callback');
});

コントローラーの実装

LINEログインによる認証処理を実装していきます。
LINEログイン後のページの遷移先は通常のログイン時と同じにしています。

app/Http/Controllers/Auth/LoginController.php
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Laravel\Socialite\Facades\Socialite;

class LoginController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = RouteServiceProvider::HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

    /**
     * 外部サービスの認証ページへリダイレクトする。
     */
    public function redirectToProvider() {
        return Socialite::driver('line')->redirect();
    }

    /**
     * 外部サービスからユーザー情報を取得し、ログインする。
     */
    public function handleProviderCallback(Request $request) {
        $line_user = Socialite::driver('line')->user();

        $user = User::firstOrCreate(
            ['line_user_id' => $line_user->id],
            ['name' => $line_user->name]
        );

        $this->guard()->login($user, true);
        return $this->sendLoginResponse($request);
    }
}

redirectメソッドの前にsetScopesメソッドやwithメソッドを使用することで取得するユーザー情報の範囲を指定したり認証のオプションを指定することができます。
指定できるパラメータは以下のURLで確認できます。
なおwithメソッドを使用するときはstateresponse_typeなどの必須パラメータは指定しないようにします。

public function redirectToProvider() {
    $nonce_token = Str::random(40);

    return Socialite::driver('line')
        ->setScopes(['openid', 'profile'])
        ->with([
            'nonce' => $nonce_token,
        ])
        ->redirect();
}

ビューの作成

ここまで実装できればあとは、LINEログイン画面へ遷移するためのリンクを設置するだけです。
この記事ではただのテキストリンクにしていますが、本来は公式でLINEログインボタンのデザインが指定されています。

<a href="{{ route('login.line.redirect') }}">LINEでログイン</a>

#まとめ
Socialiteを使用することで比較的簡単にLINEログインを実装することができました。
初めは古いバージョンのLaravelの記事を参考にしていたので一部躓いたところがありましたが、公式ドキュメントを確認しながらなんとか解決できました。
間違いや改善点などがあればご教示いただけますと幸いです。

25
16
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
25
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?