はじめに
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で設定しておきます。
'line' => [
'client_id' => env('LINE_CLIENT_ID'),
'client_secret' => env('LINE_CLIENT_SECRET'),
'redirect' => env('LINE_REDIRECT_URI')
],
イベントを追加
Socialiteに別途プロバイダーを追加している場合はapp/Providers/EventServiceProvider
へ追加の記述をします。
Laravel8からは記述方法が変わっています。
protected $listen = [
// 下記3行を追加
\SocialiteProviders\Manager\SocialiteWasCalled::class => [
\SocialiteProviders\Line\LineExtendSocialite::class.'@handle',
],
];
usersテーブルの変更
LINEログインしたユーザーから取得したプロバイダーIDを保存するためにusers
テーブルを変更します。
メールアドレスによるログイン方法も残すにはemail
とpassword
でnullを許容しておきます。
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モデルもあわせて変更します。
<?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ログインに関わる処理のルーティングを追加します。
認証関連のパッケージを導入したときにログイン用のコントローラーが作成されているので利用します。
<?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ログイン後のページの遷移先は通常のログイン時と同じにしています。
<?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
メソッドを使用するときはstate
やresponse_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の記事を参考にしていたので一部躓いたところがありましたが、公式ドキュメントを確認しながらなんとか解決できました。
間違いや改善点などがあればご教示いただけますと幸いです。