WEB/システム/IT技術ブログ

LaravelでGate機能を使ってユーザ情報に権限情報を追加します。

ユーザ毎に管理者権限などを割り振りたい場合、Laravelに用意されているGate機能を利用すると便利です。
具体的にはユーザ毎に任意の数字を割り振り、その数字により権限を割り振ることにしたいのですが、デフォルトのuserテーブルにはそのカラムが存在しません。そこでカラムを追加するところから権限機能追加の手順について確認していきます。

ちなみに今回の環境はLaravel 5.8で、Auth機能は追加済みを想定しています。
また、追加したカラムの持つ数字の意味として、以下の権限を付与するものとします。
1 : 閲覧者
50 : 編集者
100 : 管理者

システム設計として、数字を連番にしてしまうと、いざ間に新しい権限を追加しようとしたときに困るので、数字の間に余裕を持たせるのが一般的です。

userテーブルに権限情報を追加する

userテーブルに権限情報カラム「role」を追加します。カラム追加にはmigrateファイルを作成します。

> php artisan make:migration add_column_to_users_table

Laravelで通知メールを送信するしくみとしてNotificationクラスがありますが、それでテキスト(平文)メールを送る方法です。

Notificationは非常に便利で、通知メールを送るための各機能が用意されています。
但し、基本的に送信するメールタイプはHTMLメールです。正しくは「HTMLメールが受け取れない環境の場合はテキストメールを送る」といった仕様のようでうすが、あまり理解できておりません。。
個人的には通知メールは確実に届けたいので、HTMLメールではなくテキストメールのみを送信するほうが良いと考えています。HTMLメールが崩れて読めない、メッセージが伝わらないでは困りますからね。

では、実際にテキストメールを送信する方法です。
例えば、新規Notificationクラス「SampleNotification」を作成する場合、artisanコマンドで作成することができます。

> php artisan make:notification SampleNotification 

コマンドを実行すると、ファイル「…/app/Notifications/SampleNotification.php」が生成されます。デフォルトの内容は以下です。(コメントなど要点以外は省略しています)

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class SampleNotification extends Notification
{
	use Queueable;

	public function via($notifiable)
	{
		return ['mail'];
	}

	public function toMail($notifiable)
	{
		return (new MailMessage)
			->line('The introduction to the notification.')
			->action('Notification Action', url('/'))
			->line('Thank you for using our application!');
	}
}

Laravelでアプリ構築中に、画像をリサイズしたり、解像度を調整したりなど、画像加工処理を実装したかったのですが、Laravel本体にそのような機能はないようです。
少し調べてみたのですが、Laravelでは「Intervention Image」というパッケージとの相性がよさそうです。
Intervention Image – Introduction

今回はLaravel 5.8にパッケージ「Intervention Image」を組み込んでみます。

パッケージ「Intervention Image」をインストール

それでは早速パッケージ「Intervention Image」をインストールします。Laravelなので以下のようにcomposerで簡単にインストールできます。

> composer require intervention/image

パッケージのダウンロードに成功したら、以下のようにサービスプロバイダの設定「config/app.php」に追加してLaravelに組み込みます。

	'providers' => [
...
		Intervention\Image\ImageServiceProvider::class,
	],
...
	'aliases' => [
...
		'InterventionImage' => Intervention\Image\Facades\Image::class,
	],

最後に設定のキャッシュをクリアします。

> php artisan config:clear

例えば任意のフォルダ「/project/」に、Laravelで新規でプロジェクト作成すると、以下のようなフォルダが展開されます。

app
bootstrap
config
database
public
resouces
routes
...(略)

このうちフォルダ「public」が公開フォルダとなるので、ドキュメントルートに設定すればよいのですが、サーバ環境の都合上、別のフォルダを指定したい場合があります。
フレームワークであれば、1か所設定すれば解決しそうなお話ですが、Laravelではそうはいきません。

それでは、Laravel 5.8でデフォルトの公開フォルダ「/project/public/」を「/public_html/」に変更すると仮定して、設定手順を追ってみます。

ドキュメントルートの「index.php」を編集する

まず、ドキュメントルートに設置するインデックスファイル「/project/public/index.php」を「/public_html/index.php」に移動して編集します。

...
require __DIR__.'/../vendor/autoload.php';
...
$app = require_once __DIR__.'/../bootstrap/app.php';
...

上の記述部分を、以下のようにLaravel本体へのパスに調整します。

...
require __DIR__.'/../../project/vendor/autoload.php';
...
$app = require_once __DIR__.'/../../project/bootstrap/app.php';
...

一見、この対応だけでLaravelが問題なく動作しているように見えます。
但し、Laravelのコアなプログラムで「public」はハードコーディングされており、このままではストレージやファイルへのアクセスなど、公開フォルダへのアクセスが伴う処理をしようとするとズレが発生してしまいます。
例えばヘルパ関数「public_path()」を使用しても正しいパスは取得できません。

そこで、以下の対応も必要となります。

Laravelのフォームリクエストを使ってバリデーション処理を管理します。

ある日、Laravel開発中にコントローラ内でフォームバリデーションの処理を記述していました。
「コントローラの処理が増えてきたなぁ」や「この処理、他のリクエストでも使いまわすよなぁ」と考えていました。
これらの問題を解決する方法「フォームリクエスト」があるんですね。

フォームリクエストは一連のバリデーション処理を、外部クラスにまとめることができます。
フォームリクエストを利用することで、任意のリクエストで処理を呼び出すことができますし、コントローラ内のコードもスッキリさせることができます。

フォームリクエスト作成

フォームリクエストを作成します。フォームリクエストは以下のようにartisanコマンドで作成できます。

> php artisan make:request SampleRequest

コマンドを実行すると「/app/Http/Requests/SampleRequest.php」が作成されます。内容は以下の通りです。

namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class SampleRequest extends FormRequest
{
	public function authorize()
	{
		return false;
	}

	public function rules()
	{
		return [
		];
	}
}

最近、laravelやCakePHPなどcomposerを利用したPHPプロジェクトが増えてきました。
そこで、「composer.json」と「composer.lock」の違い、installやupdateの違いなど、運用方法についてのメモです。
間違っていたらご指摘ください。。

新規プロジェクト作成

新規でプロジェクトを作成する場合、ファイル「composer.json」を作成して必要なライブラリとバージョン情報を記述します。(今回「composer.json」の記述方法については割愛します)
以下のコマンドを実行すると、jsonファイルの情報を元にライブラリをインストールします。

composer install

この時、新規インストールになるのでファイル「composer.lock」が生成されます。「composer.lock」にはインストールされたライブラリ情報が出力されます。

両者の違いについて「composer.json」にはバージョンの範囲を指定することができます。指定範囲の中で最新のバージョンがインストールされます。
一方で「composer.lock」には、その時にインストールしたバージョンが出力されます。

プロジェクトインストール

例えば、先ほど作成したプロジェクトと同一のライブラリ環境を用意したい場合、先ほど生成された「composer.lock」をインストールディレクトリにコピーして、以下のコマンドを実行します。

composer install

この時「composer.json」は無視され、「composer.lock」の内容を元にライブラリがインストールされます。「composer.lock」は更新されません。

つまり「composer.lock」を利用してインストールを実行することで、別の開発者や環境で同じライブラリ環境を実現することができます。

Laravelのシーディング機能を使ってデータを移行します。

現在、とある別フレームワークで構築した旧システムをから、Laravelを利用したシステムへと移行しています。
DBのデータを移行する必要があり、バッチ処理を実装しなければいけないと考えていたのですが、Laravelにはシーディングという便利な機能があるみたいなので、早速トライします。

シーダーファイル作成

シーディングでは、まず処理を記述したシーダーファイルを用意します。
シーターファイルはartisanコマンドで作成することができます。例えば、ユーザ情報を移行する処理「UsersTableSeeder」を作成します。

> php artisan make:seeder UsersTableSeeder

コマンドを実行するとファイル「/database/seeds/UsersTableSeeder.php」が作成されます。内容は以下のとおりです。

use Illuminate\Database\Seeder;
class UsersTableSeeder extends Seeder
{
	public function run()
	{
		//
	}
}

関数「run」の中に、データ移行に必要な処理を記述します。
今回の場合は、旧システムのDBからユーザ情報を取り出し、LaravelのDBにInsertするような処理を実装しますが、その詳細は割愛します。

Laravelのバリデーションで、半角英数字をチェックするルールが用意されているのですが、日本語など全角文字には対応していないようです。

例えば、ユーザ名などに対して半角英数字「a~z」「A~Z」「0~9」を許可したいときは、以下のように「alpha_num」を追加すればチェックしてくれます。

  return Validator::make($data, [
    'name' => ['required', 'string', 'alpha_dash', 'max:255'],
  }

但し、このルールでは日本語を含む全角文字をチェックせずにスルーしてしまいます。
オープンソースあるあるですよね。日本語に標準を合わせてパッケージ開発されてないので、当然といえば当然です。
そこで今回は、全角文字をチェックするルールを追加してみます。

Laravelではコマンド1つでユーザ認証に関連したプログラムファイルやDBを生成してくれるので、とても便利です。
今回はその機能をカスタマイズして、ユーザ情報を保存するusersテーブルのカラムを追加してみたいと思います。

usersテーブルにカラムを追加する

usersテーブルに、例えばカラム「電話番号」「住所」を追加します。
カラムを追加するために、以下のコマンドでマイグレーションファイルを作成します。

> php artisan make:migration add_column_to_users_table

ファイル「database/migrations/2020_xx_xx_xxxxxx_add_column_to_users_table.php」が生成されます。
以下のように、電話番号と住所を追加する処理を追記します。

  public function up()
  {
    Schema::table('users', function (Blueprint $table) {
      $table->string('phone');  // 電話番号
      $table->string('address');  // 住所
      $table->softDeletes();  // ソフトデリート
    });
  }

  public function down()
  {
    Schema::table('users', function (Blueprint $table) {
      $table->dropColumn('phone');  // 電話番号
      $table->dropColumn('address');  // 住所
      $table->dropSoftDeletes();  // ソフトデリート
    });
  }

ファイルを保存したら、マイグレーションを実行します。

> php artisan migrate

DBのusersテーブルを確認すると、カラム「phone」と「address」が追加されてるのが確認できます。

Laravel 5.xで用意されている認証機能は便利です。
ただデフォルトのまま使うと、本人認証なしで簡単に新規ユーザを作成できてしまいます。
具体的には新規登録画面で「ユーザ名」「メールアドレス」「パスワード」「確認用メールアドレス」を入力するだけで新規ユーザ登録が完了してしまいます。
このままだと、例えばロボットなどに大量に架空ユーザを登録されるなど懸念されます。

最近では、新規登録画面で必要情報を入力した後に、入力したメールアドレス宛に本人確認用のURLを送信して、ユーザ登録を完了するフローが主流です。
Laravelにもこのメールアドレス確認機能(Email Verification)が用意されてるようなので、早速試してみます。

認証機能を準備

はじめに準備として、以下のコマンドを実行すると、認証に必要なルートやビューを生成してくれます。
既に実行済みの場合は、こちらをスキップしてもらって構いません。

> php artisan make:auth

Monthly Archives