20200906のPHPに関する記事は15件です。

IISでCakePHP3を動かしたら真っ白なページが表示された場合の解決策

0.はじめに

色々なサイトを見ながらCakePHP3のチュートリアルを進めていた際に、
localhost/cmsと入力したのに真っ白なページが表示されてしまった。
しかも、そもそもlocalhost/phpinfo.phpすらも真っ白だった。

しかし、原因を調べようにもCakePHP3を使うにあたってIISを用いることが珍しいのか、
なかなか自分の現象を解決する方法が書いてあるサイトが見つからなかった。

結論から言うとIISの設定不足だったのだが、見つけるのに苦労したのでここに記しておく。
ただし、IISでCakePHP3を動かす方法全体を書いているわけではないので注意
(後ほどリンクを貼っておくかも。もしくは自分でまとめるか)

1.ハンドラーマッピング

まずphpinfo.phpに関してはハンドラーマッピングの設定が漏れていた。
詳しくは調べていないが、.phpのモジュールマッピングを設定に組み込まないといけないらしい。
以下に簡単に設定方法を記載する。上の言葉だけで解決した人は作業に進んでもらって大丈夫だ。

1.IISからハンドラーマッピングを選択する

image.png

2.右のメニューから「モジュールマップの追加」を選択する

色々似たようなものがあるが、モジュールマップの追加を選択。
ちなみに左側の一覧で選択されているのが今回追加するモジュールマップというもの。
image.png

3.必要項目を入力してOKボタンを押す

画像はモジュールマップの編集のものになっているが、
モジュールマップの追加と同じ構成なので許してほしい。

要求パスモジュール画像の通りに入力。
実行可能ファイル(オプション)ご自身の環境のパスを参考に入力。
名前は任意です。自分は適当にPHPなんて名前を付けました。
image.png

ハンドラーマッピングの設定については以上です。
これでlocalhost/phpinfo.phpに飛んだらPHPの設定が表示されるかもしれません。
(phpinfo.phpを作成している前提の話ですが)

2.既定のドキュメント

こちらこそ本当に基礎の基礎なのか全然出てこなかった。
URL書き換えもあるし、web.configも問題ないのになぜlocalhost/cmsに飛ばない!ってなってた。
簡単に言うと、既定のドキュメントにindex.phpを入れる。これだけでした。
こちらも先ほどと同様に簡単に説明。

1.IISから既定のドキュメントを選択する

image.png

2.右のメニューから「追加」を選択する

image.png

3.「index.php」を入力してOKボタンを押す

image.png

これでOK。無事URL書き換えが実行されてlocalhost/cmsと入力しただけでindex.phpを開いてくれるはず。

9.最後に

最初にも書いたが、これはあくまで自分が見つけるのに時間のかかった部分だけをまとめたに過ぎない。
本当にIISでCakePHP3を動かすには他にも色々な設定が必要になる。
(それこそURL書き換えやDB接続にもちょっとした難所があったり……)

まあ、色々と書いたけど、少しでも自分と同じところで躓いている人の助けになれればとまとめてみました。
一人でもこの記事のおかげで開発が停滞する時間が短縮できる人がいれば幸いです。

初記事なので、文章として読みにくいところとか、色々と指摘があればどんどんお願いします。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel で array 型のリクエストパラメータのバリデーション

PHP-7.2 Laravel-6.x

Laravel で array 型として扱われるようなリクエストパラメータのバリデーションの記述に関するメモです。

実装

下記の例の Request Parameter にはリクエストパラメータを $request->all() で取得したときに得られる array を記述します。
Validation にはとバリデーションルールを表す array を記述します。

それぞれの変数 $data$rules に対して Validator::validate($data, $rules) を Tinker 等で実行すればバリデーションが効いているか試すことができます。

例1. key を省略した array

  • Request Parameter
$data = [
    'article_ids' => [1, 23, 456],
]
  • Validation
$rules = [
    'article_ids' => 'required|array',
    'article_ids.*' => 'int',
];

例2. key と value の組で構成された array

  • Request Parameter
$data = [
    'ingredients' => [
        'egg' => true,
        'peanuts' => false,
        'others' => 'water'
    ],
];
  • Validation
$rules = [
    'ingredients' => 'required|array',
    'ingredients.egg' => 'required|boolean',
    'ingredients.peanuts' => 'required|boolean',
    'ingredients.others' => 'string',
];

例3. ネストした array

  • Request Parameter
$data = [
    'person' => [
        ['first_name' => 'Taro', 'last_name' => 'Tanaka'],
        ['first_name' => 'Hanako', 'last_name' => 'Yamada'],
    ],
];
  • Validation
$rules = [
    'person' => 'required|array',
    'person.*.first_name' => 'required_with:person.*.last_name|string',
    'person.*.last_name' => 'required_with:person.*.first_name|string',
];

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【laravel+mysql】新規でアプリケーションを立上げ、初めてのphp artisan migrateで詰まった件

どんな問題?

初めてPHP言語を使用して、Webアプリケーションを作成するためにlaravelとmysqlで開発環境を整え、新規作成したテーブルをmigrateした際にエラーが発生し、正常にテーブルが作成できない。

エラーの内容

ターミナルで $ php artisan migrateコマンドを入力したところ、以下のようなエラーが発生しました。
6行目の通り、1050 Table 'users' already exists...とあるように「既にuserテーブルは存在あるよ」ということです。

ターミナル
$ php artisan migrate
Migrating: 2014_10_12_000000_create_users_table

   Illuminate\Database\QueryException 

  SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'users' already exists (SQL: create table `users` (`id` bigint unsigned not null auto_increment primary key, `name` varchar(255) not null, `email` varchar(255) not null, `email_verified_at` timestamp null, `password` varchar(255) not null, `remember_token` varchar(100) null, `created_at` timestamp null, `updated_at` timestamp null) default character set utf8mb4 collate 'utf8mb4_unicode_ci')

  at vendor/laravel/framework/src/Illuminate/Database/Connection.php:671
    667|         // If an exception occurs when attempting to run a query, we'll format the error
    668|         // message to include the bindings with SQL, which will make this exception a
    669|         // lot more helpful to the developer instead of just the database's errors.
    670|         catch (Exception $e) {
  > 671|             throw new QueryException(
    672|                 $query, $this->prepareBindings($bindings), $e
    673|             );
    674|         }
    675| 

      +9 vendor frames 
  10  database/migrations/2014_10_12_000000_create_users_table.php:24
      Illuminate\Support\Facades\Facade::__callStatic("create")

      +22 vendor frames 
  33  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

前提

macOS ver10.15.4
laravel ver4.0.0導入済み
mysql ver5.6.47導入済み
sequelproに接続済み

エラー発生までの流れ

ターミナル上で

ターミナル
$ laravel new [プロジェクト名]

コマンドで新規プロジェクト作成した際、userテーブルも自動生成されます。(password_resetsテーブルも自動生成されます。)

今回、追加でitemテーブルを作ろうと思い、

ターミナル
$ php artisan make:migration create_items_table

でitemテーブルのマイグレーションファイルを作成し、

ターミナル
$ php artisan migrate

を実行したところ、上記の通り1050 Table 'users' already exists...というエラーが出て、itemテーブルが作成できませんでした。

対処方法

userマイグレーションファイルを以下のように変更しました。

変更前

userマイグレーションファイル
上段省略
class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }
以下省略

変更後

userマイグレーションファイル
上段省略
class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        if (Schema::hasTable('users')) {
            // usersテーブルが存在していればリターンする
            return;
        }
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }
以下省略

userのマイグレーションファイルのpublic function up() の中身に

userマイグレーションファイル
if (Schema::hasTable('users')) {
            // usersテーブルが存在していればリターンする
            return;

の記述を入れて存在しているテーブルをリターンさせたところ、migrateが通りました。

なお、userを解決した後、password_resetsテーブルについても同様の現象が発生したため、同じ要領で対応しました。

最後に

phpに関しては初学者のため、まだまだ解っていないことが多いので、他に最善な解決方法等がありましたらご指摘いただけますと幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【PHP】フラッシュメッセージの実装

PHPについて学習内容を備忘録としてまとめます。
今回はフラッシュメッセージをポートフォリオに実装したので、実装方法を記録します。

フラッシュメッセージ実装

全体の流れとしては空のフォームがあった場合に該当のエラーメッセージを格納し、
ログイン画面でエラーメッセージを表示するという流れになっております。

まずフォームが空かを確認し処理を行います。
これで該当のフォームが空のとき、エラーメッセージに値を格納することができます。

//login_check.php(ログイン過程のファイルです)

if(empty($staff_code)){
    $error_messages['code'] = "コードを入力してください";
  }

if(empty($staff_pass)) {
    $error_messages['pass'] = "パスワードを入力してください";
  }

余談にはなりますが、md5などで値をハッシュ化するとフォームは空でも値が入ってしまいemptyで処理できなくなります。

//$staff_passは空

$staff_pass=md5($staff_pass);

//$staff_passに値が入る

if(empty($staff_pass)) {
    $error_messages['pass'] = "パスワードを入力してください";
  }

//上記処理が実行されない

error_masseagesに値が格納されましたら、今度はセッションに値を格納します。
このときにフラッシュメッセージの種類によって色などを変更したい際は$flash_typeも定義します。

//login_check.php

if( isset($_SESSION['flash']) ){
    $flash_messages = $_SESSION['flash']['message'];
    $flash_type = $_SESSION['flash']['type'];
  }
  unset($_SESSION['flash']);

最後にログイン画面にてフラッシュメッセージを表示させます。

//login_form.php

    <?php if (isset($flash_messages)): ?>
      <?php foreach ((array)$flash_messages as $message): ?>
        <p class ="flash_message <?= $flash_type ?>"><?= $message?></p>
      <?php endforeach ?>
    <?php endif ?>

実装画面

image.png

image.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JetPack のサイトアクセラレーター有効時にフルサイズ画像が縮小されてしまう問題への対処法

問題

WordPress で JetPack の サイトアクセラレーターを有効化静的ファイルの読み込みをスピードアップ を ON にしていると、投稿内で読み込まれる画像の幅が、画像サイズ: フルサイズ を指定していても、1024px に縮小されたものになってしまいます。

原因

JetPack は global $content_width を参照して、画像の最大幅を決定しているため1

解消方法

functions.php 等に以下の内容を追記し $global $content_width を上書きします2

functions.php
<?php
// ...

( function() {
    global $content_width;
    $content_width = 1920; // 想定される画像の最大幅を指定する.
} )();

// ...

備考

将来的3に、add_theme_support()global $content_width を変更できるようになる可能性があります4

参考ページ


  1. したがって、テーマ内で global $content_width が指定されている場合は、1024px 以外の幅になる場合もあります。 

  2. 子テーマやプラグイン内での指定は未検証です。add_action( 'after_setup_theme', $function_to_add ) を使う必要があるかもしれません。 

  3. この記事の執筆時点での最新 WordPress バージョンは、5.5.1。  

  4. Cf. #21256 (New theme feature - add_theme_support( 'content-width', $defaults )) – WordPress Trac

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

わかりやすい変数名の付け方

プログラミング勉強日記

2020年9月6日
わかりやすいコードを書くために必要不可欠であるわかりやすい変数名の付け方をまとめる。変数名をわかりやすくすることで、読みやすく、コードの間違いにも気づきやすくなる。

PHPの変数の書き方

  • PHPの場合は変数は$から始まる
  • そのあとは半角英数字とアンダーバー(_)が使用することができる。($のあとにすぐ数字を使うことはできない)

以上のルールに違反すると、実行時にエラーとなってしまう。

また、ルール(命令規則)ではないが以下の決まりもある。

  • 大文字と小文字は区別される。
  • 変数名を全て大文字にすることもできるが、特別な意味を持つ変数を全て大文字にすることがあるので、全て大文字にはしないほうがいい。

ルールではないが、複数単語になる場合は
単語と単語の間をアンダーバー(_)で区切るか、2語目以降の先頭の文字を大文字にする。

☆ポイント
 複数の単語を使うときはどちら(先頭を大文字にするのか_を使うのか)を決めておく。

複数単語の例
//悪い例
$userid = "123";
$user_name = "Tanaka";
$userGroup = "A";

//良い例
$userID = "123";
$userName = "Tanaka";
$userGroup ="A";

変数名の付け方

 変数の中身は何を格納するのか。中身は何なのかを示したものにする。つまり、変数がどの用途で使われるのかわかりやすい名前にする。
 変数名は長すぎず短すぎずちょうどいい長さにする。
 データベースのテーブルから取得したデータには、テーブルの名前やカラム名をそのまま付けるとわかりやすくなる。

//悪い例
$data //何のデータかわからない
$a    //何を格納しているのかわからない
$var  //何の変数(variable)かわからない

//良い例
$error_message //エラーメッセージが格納されている
$user_id       //ユーザのidが格納されている
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

How to make delete button in laravel (File Upload Site #3)

  1. ルートを作成
web.php
Route::delete('files/{id}', 'FilesController@destroy')->name('deletefile');
  1. View ファイルにフォームを追加する
home.blade.php
<th>
<form action="{{ route('deletefile', $file->id) }}" method="POST">
@csrf @method('DELETE')
<button type="submit" class="btn btn-outline-danger btn-delete"><i class="fa fa-trash"></i>Delete</button>
</form>
</th>

@csrf はクロスサイトリクエストフォージェリからの防蟻です。

3.コントローラーにfunction追加

filescontroller.php
public function destroy($id)
    {
        $del = File::find($id);
        Storage::delete($del->path);
        $del->delete();
        return redirect('/home');
    }

Screen Shot 2020-09-06 at 15.21.01.png
こんな感じです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker × Laravel 自動整形するコンテナを構築する

PHP CS Fixer とは

PHP CS Fixer (PHP Coding Standards Fixer) とは、その名の通りPHPのコードをコーディング規約に沿うよう修正してくれるツールです。

環境

https://github.com/ucan-lab/docker-laravel

こちらのリポジトリの構成を例にします。

docker-compose.ymlの編集

docker-compose.yml
services:
  cs:
    image: herloct/php-cs-fixer
    volumes:
      - ./backend:/project

services.cs を追記します。

コマンド

# 自動整形しない(差分表示のみ)
$ docker-compose run cs fix --dry-run -v --diff --diff-format udiff .

# 自動整形する
$ docker-compose run cs fix -v --diff --diff-format udiff .

Makefile

コマンドが長いのでMakefileを用意しておくと良いです。

dry-cs:
    docker-compose run cs fix --dry-run -v --diff --diff-format udiff .
fix-cs:
    docker-compose run cs fix -v --diff --diff-format udiff .

下記のコマンドで実行できるようになります。

$ make dry-cs
$ make fix-cs
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker × Laravel コードを自動整形するコンテナを構築する

PHP CS Fixer とは

PHP CS Fixer (PHP Coding Standards Fixer) とは、その名の通りPHPのコードをコーディング規約に沿うよう修正してくれるツールです。

前提

当記事は上記の記事の補足になる記事です。

docker-compose.ymlの編集

docker-compose.yml
services:
  cs:
    image: herloct/php-cs-fixer
    volumes:
      - ./backend:/project

services.cs を追記します。

コマンド

# 自動整形しない(差分表示のみ)
$ docker-compose run cs fix --dry-run -v --diff --diff-format udiff .

# 自動整形する
$ docker-compose run cs fix -v --diff --diff-format udiff .

Makefile

コマンドが長いのでMakefileを用意しておくと良いです。

dry-cs:
    docker-compose run cs fix --dry-run -v --diff --diff-format udiff .
fix-cs:
    docker-compose run cs fix -v --diff --diff-format udiff .

下記のコマンドで実行できるようになります。

$ make dry-cs
$ make fix-cs

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

よくわかるPHPの教科書でリンク先のページが真っ白になる【500 (Internal Server Error)】の解決法

よくわかるPHPの教科書で学習中にリンク先のページが真っ白になるというエラーを解決する方法をサクッとまとめます。
(初学者のエラー解決方の一例です。低レベルですがご了承ください)

今回は「削除機能をつける」の段階でのエラーでしたが全般的に起こりうるエラーだと思います(?)

【エラー詳細】
スクリーンショット 2020-09-06 10.45.36.png
削除する為のコードを書いて削除ボタンに設定したリンクにアクセスすると、真っ白になりました。
リンク先を見てみると

delete.php=?id=18

となっているので、削除したい投稿にはアクセスできているみたいです。

【解決手順】
なにが起こっているのかわからなかったので、デベロッパーツールにて確認します
スクリーンショット 2020-09-06 10.45.53.png

この「console」の部分を見てみると...

スクリーンショット 2020-09-06 10.45.59.png

なにやらエラーが出ています。

Failed to load resource: the server responded with a status of 500 (Internal Server Error)

調べてみると...
webサーバー上のエラー?っていうのが多く出てきましたが...(よくわかrん)

【500 (Internal Server Error)】

というのはかなりザックリしたエラーのようで、原因が色々あって特定が難しいらしい...

さらに調べると、もっと詳細のエラーを画面に出す為のコードがあるみたいで、下記コードをdelete.phpの先頭に記述しました。

ini_set("display_errors", 1);
error_reporting(E_ALL);      

これを記載すると

<?php

ini_set("display_errors", 1);
error_reporting(E_ALL);      

session_start();
require('dbconnect.php');

if(isset($_SESSION['id'])){
    $id = $_REQUEST['id'];

    $messages = $db->prepare('SELECT * FROM posts WHERE id=?');
    $messages->execute(array($id));
    $message = $messeges->fetch();

    if($message['member_id'] == $_SESSION['id']){
        $del = $db->prepare('DELETE FROM posts WHERE id=?');
        $del->execute(array($id));
    }
}

header('Location: index.php');
exit();
?>

こんな感じ。

上書き保存してもう一度、削除リンクにアクセスしてみると...

スクリーンショット 2020-09-06 11.15.04.png

なにやら画面にエラーが表示されました。(ワクワク)

google翻訳さんに通訳してもらうと、
Fatal error  ・・・致命的だそうです。

そして

「delete.phpの14行目がダメだぞ!」
って言われてるみたいです。

そこでdelete.phpの14行目を確認してみると..

スクリーンショット 2020-09-06 11.13.03.png

messagesの一部が

a  →  e

になっておりました。(貴様が原因か...!)

以上
スペルを直すと、正常に動作しました。

エラーの8〜9割はスペルミスだな〜と勉強していて感じます。
正確に打つこともそうですが、今回のようにエラー箇所が分かるようになると探す手間も省けるので、使いこなせるようになりたいです。
あと、エラーは間違いを教えてくれる優しい奴なんだな〜と感じました。

おしまい

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHPでのオブジェクト型データへのアクセス

型の種類でobjectというものがあります。配列のような使い方をするようですが、その要素へのアクセスの仕方です。

example.php
$a = $object->['property'];

変数$a$objectpropertyプロパティの値を格納するという意味になります。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【PHP/JavaScript】配列に大きい添字を指定して値を代入したときのサイズ

動機

 Webアプリを開発する際、ユーザーID(整数)をインデックスにした配列を作ったときに、無駄に大きい配列になるのでは??

結論

 PHPでは配列、JavaScriptではMapを使用すると、サイズが無駄に大きくならない。

PHPの場合

 大きい添字を指定しても、問題はなさそう。

$array = [];
$array[100] = 'hoge';

echo count($array);    // 1

JavaScriptの場合

 大きい添字を指定すると、あいているところにemptyが挿入された配列になった。

let array = [];
array[100] = 'hoge';

console.log(array);         // [empty x 100, "hoge"]
console.log(array.length);  // 101

Mapを使用すると、PHPの配列と似たような振る舞いになった。

let map = new Map([[100, 'hoge']]);

console.log(map);           // Map(1) {100 => "hoge"}
console.log(map.size);      // 1

上限は?

PHPの場合

 整数の上限は、プラットフォームに依存しており、約20億 or 約900京となる。(参考
 自分の環境では900京(9 * 10^18)まで使用できた。

$array = [];
$n = 9 * 10 ** 18;
$array[$n] = 'hoge';

echo count($array);    // 1

 900京のユーザーがいても、ちゃんと違うユーザーであると識別できるらしい。

$n = 9 * 10 ** 18;
$m = $n - 1;
var_dump($n == $m);    // false

JavaScriptの場合

 安全な整数値の上限(2^53 - 1)があり、Number.MAX_SAFE_INTEGERで利用できる(参考
 PHPよりは上限が小さい(~9.0 * 10^15)
 Mapを使用する場合は、この上限値以内であれば、問題なさそう。

let n = Number.MAX_SAFE_INTEGER;
let map = new Map([[n - 1, 'hoge']]);

console.log(map);               // Map(1) {9007199254740990 => "hoge"}
console.log(map.size);          // 1

let m = n - 1;
console.log(n === m);           // false
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

配列に大きい添字を指定して値を代入したときのサイズ

動機

 Webアプリを開発する際、ユーザーID(整数)をインデックスにした配列を作ったときに、無駄に大きい配列になるのでは??

結論

 PHPでは配列、JavaScriptではMapを使用すると、サイズが無駄に大きくならない。

PHPの場合

 大きい添字を指定しても、問題はなさそう。

$array = [];
$array[100] = 'hoge';

echo count($array);    // 1

JavaScriptの場合

 大きい添字を指定すると、あいているところにemptyが挿入された配列になった。

let array = [];
array[100] = 'hoge';

console.log(array);         // [empty x 100, "hoge"]
console.log(array.length);  // 101

Mapを使用すると、PHPの配列と似たような振る舞いになった。

let map = new Map([[100, 'hoge']]);

console.log(map);           // Map(1) {100 => "hoge"}
console.log(map.size);      // 1

上限は?

PHPの場合

 整数の上限は、プラットフォームに依存しており、約20億 or 約900京となる。(参考
 自分の環境では900京(9 * 10^18)まで使用できた。

$array = [];
$n = 9 * 10 ** 18;
$array[$n] = 'hoge';

echo count($array);    // 1

 900京のユーザーがいても、ちゃんと違うユーザーであると識別できるらしい。

$n = 9 * 10 ** 18;
$m = $n - 1;
var_dump($n == $m);    // false

JavaScriptの場合

 安全な整数値の上限(2^53 - 1)があり、Number.MAX_SAFE_INTEGERで利用できる(参考
 PHPよりは上限が小さい(~9.0 * 10^15)
 Mapを使用する場合は、この上限値以内であれば、問題なさそう。

let n = Number.MAX_SAFE_INTEGER;
let map = new Map([[n, 'hoge']]);

console.log(map);               // Map(1) {9007199254740991 => "hoge"}
console.log(map.size);          // 1

let m = n - 1;
console.log(n === m);           // false
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

お手元のPHPファイルをphp-cs-fixerでチェックする

コマンド

# 自動整形しない(差分表示のみ)
$ docker run -v $(pwd):/project herloct/php-cs-fixer fix --dry-run -v --diff --diff-format udiff .

# 自動整形する
$ docker run -v $(pwd):/project herloct/php-cs-fixer fix -v --diff --diff-format udiff .

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel6 ユーザと管理者の認証を分けて管理者の認証情報のみ名前とパスワードだけにする

目的

  • ユーザと管理者とで認証を分ける方法をまとめる。

実施環境

  • ハードウェア環境
項目 情報
OS macOS Catalina(10.15.5)
PC MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)
プロセッサ 2 GHz クアッドコアIntel Core i5
メモリ 32 GB 3733 MHz LPDDR4
グラフィックス Intel Iris Plus Graphics 1536 MB
  • ソフトウェア環境
項目 情報 備考
PHP バージョン 7.4.3 Homwbrewを用いて導入
Laravel バージョン 6.18.35 commposerを用いてこちらの方法で導入→Mac Laravelの環境構築を行う
MySQLバージョン 8.0.19 for osx10.13 on x86_64 Homwbrewを用いてこちらの方法で導入→Mac HomebrewでMySQLをインストールする

前提条件

  • 先の実施環境に近い環境が整っていること。
  • Laravelは最新バージョン用に構築しているがアプリ作成コマンド実行時に5.6を指定して作成する。

前提情報

  • DockerやAWSなどは使用せずにMacのローカル環境に直接Laravelアプリを作成する。
  • 若干難易度が高い作業であるためなるべくわかりやすい様に丁寧に記載する。
  • 本記事の内容を最初から実施していけば誰でもユーザと管理者別々での認証を行えることを目指す。
  • 管理者認証情報は管理者名、メールアドレス、パスワードとする。
  • 作業複雑化を避けるため管理者用のパスワードはアプリ側から変更できる様にしない。
  • 既存のAuth認証コントローラを追記編集して管理者の認証機能を作成する。
  • 下記のドキュメントを参考に必要名部分のみを抜粋して実装する。また、説明をより分かりやすくするために若干実装の順番を変更する。

読後感

  • Laravel5.6のでユーザ認証と管理者認証機能のついたアプリを作成することができる。

概要

  1. データベースの作成
  2. Laravelアプリの作成と初期設定
  3. ユーザ認証機能作成
  4. 管理者情報用テーブルの準備
  5. ガードとプロバイダの追加
  6. コントローラの修正
  7. 認証用ページの作成
  8. 認証後遷移ページの作成
  9. ルーティングの記載と認証後遷移ページの設定と例外時の処理の記載
  10. 確認

詳細

  1. データベースの作成

    1. 下記コマンドを実行してMySQLにターミナルからログインする。(MySQLのrootユーザのパスワードを忘れてしまった方はこちら→Mac ローカル環境の MySQL 8.x のrootパスワードを忘れた時のリセット方法)

      $ mysql -u root -p
      
    2. 下記SQLを実行して「multi_auth_laravel_6」データベースを作成する。

      create database multi_auth_laravel_6;
      
    3. 下記SQLを実行してデータベース一覧を出力して「multi_auth_laravel_6」が含まれていることを確認する。確認後、MySQLをログアウトする。

      show databases;
      
  2. Laravelアプリの作成と初期設定

    1. Laravelアプリを作成する任意のディレクトリに移動する。
    2. 下記コマンドを実行して「multi_auth_laravel_6」というLaravel6のアプリを作成する。(完了まで時間がかかる可能性があるので少し待機する。)

      $ composer create-project laravel/laravel multi_auth_laravel_6 "6.*"
      
    3. 下記コマンドを実行して作成されたアプリ名ディレクトリに移動する。以後のコマンドは特に記載がない場合、このmulti_authディレクトリ内部で実行する物とする。

      $ cd multi_auth
      
    4. 下記コマンドを実行して.envファイルを開く。

      $ vi .env
      
    5. 下記の様に.envファイルのデータベースの記述を修正する。

      multi_auth_laravel_6/.env
      DB_DATABASE=multi_auth_laravel_6
      DB_USERNAME=root
      DB_PASSWORD=mysql -u root -pコマンドを実行した際に入力したパスワード
      
    6. 修正後の.envファイルの全体の内容を記載する。

      multi_auth_laravel_6/.env
      APP_NAME=Laravel
      APP_ENV=local
      APP_KEY=アプリキーの記載は各個人で異なります。
      APP_DEBUG=true
      APP_URL=http://localhost
      
      LOG_CHANNEL=stack
      
      DB_CONNECTION=mysql
      DB_HOST=127.0.0.1
      DB_PORT=3306
      DB_DATABASE=multi_auth_laravel_6
      DB_USERNAME=root
      DB_PASSWORD=皆さんの環境のMySQLのrootユーザのパスワード
      
      BROADCAST_DRIVER=log
      CACHE_DRIVER=file
      QUEUE_CONNECTION=sync
      SESSION_DRIVER=file
      SESSION_LIFETIME=120
      
      REDIS_HOST=127.0.0.1
      REDIS_PASSWORD=null
      REDIS_PORT=6379
      
      MAIL_MAILER=smtp
      MAIL_HOST=smtp.mailtrap.io
      MAIL_PORT=2525
      MAIL_USERNAME=null
      MAIL_PASSWORD=null
      MAIL_ENCRYPTION=null
      MAIL_FROM_ADDRESS=null
      MAIL_FROM_NAME="${APP_NAME}"
      
      AWS_ACCESS_KEY_ID=
      AWS_SECRET_ACCESS_KEY=
      AWS_DEFAULT_REGION=us-east-1
      AWS_BUCKET=
      
      PUSHER_APP_ID=
      PUSHER_APP_KEY=
      PUSHER_APP_SECRET=
      PUSHER_APP_CLUSTER=mt1
      
      MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
      MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
      
    7. 下記コマンドを実行して初期マイグレーションファイルをマイグレートする。

      $ php artisan migrate
      
    8. 下記コマンドを実行してローカルサーバを起動する。

      $ php artisan serve
      
    9. 下記にアクセスしてLaravelの初期画面が表示されることを確認する。

  3. ユーザ認証機能作成

    1. 下記コマンドを実行してユーザ認証機能を作成する。

      $ composer require laravel/ui "^1.0" --dev
      $ php artisan ui vue --auth
      $ npm install && npm run dev
      
    2. 下記コマンドを実行してローカルサーバを起動する。

      $ php artisan serve
      
    3. 下記にアクセスしてLaravelの初期画面を開く。

    4. 右上の「REGISTER」をクリックする。

      Laravel.png

    5. 各種情報を入力して「Register」をクリックする。

      Laravel-2.png

    6. 「Register」をクリック後角の画面に遷移することを確認する。

      Laravel-3.pngLaravel.png

  4. 管理者情報用テーブルの準備

    1. 下記コマンドを実行してAdminモデルファイルとadminsテーブル作成用マイグレーションファイルを作成する。

      $ php artisan make:model Admin -m
      
    2. 下記コマンドを実行して先に作成したマイグレーションファイルを開く。(YYYY_MM_DD_XXXXXXの部分はマイグレーションファイル作成日により異なる。)

      $ vi database/migrations/YYYY_MM_DD_XXXXXX_create_admins_table.php
      
    3. 開いたマイグレーションファイルを下記の様に追記する。

      multi_auth_laravel_6/database/migrations/YYYY_MM_DD_XXXXXX_create_admins_table.php
      <?php
      
      use Illuminate\Support\Facades\Schema;
      use Illuminate\Database\Schema\Blueprint;
      use Illuminate\Database\Migrations\Migration;
      
      class CreateAdminsTable extends Migration
      {
          /**
           * Run the migrations.
           *
           * @return void
           */
          public function up()
          {
              Schema::create('admins', function (Blueprint $table) {
                  $table->increments('id');
                  //下記から追加
                  $table->string('name');
                  $table->string('email')->unique();
                  $table->string('password');
                  $table->boolean('is_super')->default(false);
                  $table->rememberToken();
                  //上記までを追加
                  $table->timestamps();
              });
          }
      
          /**
           * Reverse the migrations.
           *
           * @return void
           */
          public function down()
          {
              Schema::dropIfExists('admins');
          }
      }
      
      
    4. 下記コマンドを実行して今記載したマイグレーションファイルをマイグレートする。

      $ php artisan migrate
      
    5. 下記コマンドを実行して先に作成したモデルファイルを開く。

      $ vi app/Admin.php
      
    6. 開いたモデルファイルの内容を全て削除し、下記の内容をコピーアンドペーストで記載する

      multi_auth_laravel_6/app/Admin.php
      <?php
      
      namespace App;
      
      use Illuminate\Notifications\Notifiable;
      use Illuminate\Foundation\Auth\User as Authenticatable;
      
      class Admin extends Authenticatable
      {
          use Notifiable;
      
          protected $guard = 'admin';
      
          protected $fillable = [
              'name', 'email', 'password',
          ];
      
          protected $hidden = [
              'password', 'remember_token',
          ];
      }
      
  5. ガードとプロバイダの追加

    1. 下記コマンドを実行しガードとプロバイダを定義しているファイルを開く。

      $ vi  config/auth.php
      
    2. ガードの記載を下記の様に追記する。

      multi_auth_laravel_6/config/auth.php
      /*
      |--------------------------------------------------------------------------
      | Authentication Guards
      |--------------------------------------------------------------------------
      |
      | Next, you may define every authentication guard for your application.
      | Of course, a great default configuration has been defined for you
      | here which uses session storage and the Eloquent user provider.
      |
      | All authentication drivers have a user provider. This defines how the
      | users are actually retrieved out of your database or other storage
      | mechanisms used by this application to persist your user's data.
      |
      | Supported: "session", "token"
      |
      */
      
      'guards' => [
          'web' => [
              'driver' => 'session',
              'provider' => 'users',
          ],
      
          'api' => [
              'driver' => 'token',
              'provider' => 'users',
          ],
          //下記を追記
          'admin' => [
              'driver' => 'session',
              'provider' => 'admins',
          ],
          //上記までを追記
      ],
      
    3. 同ファイル内のプロバイダの記載も追記を行う。

      multi_auth_laravel_6/config/auth.php
      /*
      |--------------------------------------------------------------------------
      | User Providers
      |--------------------------------------------------------------------------
      |
      | All authentication drivers have a user provider. This defines how the
      | users are actually retrieved out of your database or other storage
      | mechanisms used by this application to persist your user's data.
      |
      | If you have multiple user tables or models you may configure multiple
      | sources which represent each model / table. These sources may then
      | be assigned to any extra authentication guards you have defined.
      |
      | Supported: "database", "eloquent"
      |
      */
      
      'providers' => [
          'users' => [
              'driver' => 'eloquent',
              'model' => App\User::class,
          ],
          //下記を追記する
          'admins' => [
              'driver' => 'eloquent',
              'model' => App\Admin::class,
          ],
          //上記までを追記する
      
          // 'users' => [
          //     'driver' => 'database',
          //     'table' => 'users',
          // ],
      ],
      
    4. 追記後のmulti_auth_laravel_6/config/auth.phpのファイルの全体を下記に記載する。

      multi_auth_laravel_6/config/auth.php
      <?php
      
      return [
      
          /*
          |--------------------------------------------------------------------------
          | Authentication Defaults
          |--------------------------------------------------------------------------
          |
          | This option controls the default authentication "guard" and password
          | reset options for your application. You may change these defaults
          | as required, but they're a perfect start for most applications.
          |
          */
      
          'defaults' => [
              'guard' => 'web',
              'passwords' => 'users',
          ],
      
          /*
          |--------------------------------------------------------------------------
          | Authentication Guards
          |--------------------------------------------------------------------------
          |
          | Next, you may define every authentication guard for your application.
          | Of course, a great default configuration has been defined for you
          | here which uses session storage and the Eloquent user provider.
          |
          | All authentication drivers have a user provider. This defines how the
          | users are actually retrieved out of your database or other storage
          | mechanisms used by this application to persist your user's data.
          |
          | Supported: "session", "token"
          |
          */
      
          'guards' => [
              'web' => [
                  'driver' => 'session',
                  'provider' => 'users',
              ],
      
              'api' => [
                  'driver' => 'token',
                  'provider' => 'users',
              ],
              //下記を追記する
              'admin' => [
                  'driver' => 'session',
                  'provider' => 'admins',
              ],
              //上記までを追記する
          ],
      
          /*
          |--------------------------------------------------------------------------
          | User Providers
          |--------------------------------------------------------------------------
          |
          | All authentication drivers have a user provider. This defines how the
          | users are actually retrieved out of your database or other storage
          | mechanisms used by this application to persist your user's data.
          |
          | If you have multiple user tables or models you may configure multiple
          | sources which represent each model / table. These sources may then
          | be assigned to any extra authentication guards you have defined.
          |
          | Supported: "database", "eloquent"
          |
          */
      
          'providers' => [
              'users' => [
                  'driver' => 'eloquent',
                  'model' => App\User::class,
              ],
              //下記を追記する
              'admins' => [
                  'driver' => 'eloquent',
                  'model' => App\Admin::class,
              ],
              //上記までを追記する
              // 'users' => [
              //     'driver' => 'database',
              //     'table' => 'users',
              // ],
          ],
      
          /*
          |--------------------------------------------------------------------------
          | Resetting Passwords
          |--------------------------------------------------------------------------
          |
          | You may specify multiple password reset configurations if you have more
          | than one user table or model in the application and you want to have
          | separate password reset settings based on the specific user types.
          |
          | The expire time is the number of minutes that the reset token should be
          | considered valid. This security feature keeps tokens short-lived so
          | they have less time to be guessed. You may change this as needed.
          |
          */
      
          'passwords' => [
              'users' => [
                  'provider' => 'users',
                  'table' => 'password_resets',
                  'expire' => 60,
              ],
          ],
      
      ];
      
  6. コントローラの修正

    1. 下記の二つのコントローラを修正する。
      • multi_auth_laravel_6/app/Http/Controllers/Auth/LoginController.php
      • multi_auth_laravel_6/app/Http/Controllers/Auth/RegisterController.php
    2. 下記コマンドを実行してログインを司るコントローラファイルを開く。

      $ vi app/Http/Controllers/Auth/LoginController.php
      
    3. 開いたコントローラファイルを下記の様に修正する。

      multi_auth_laravel_6/app/Http/Controllers/Auth/LoginController.php
      <?php
      
      namespace App\Http\Controllers\Auth;
      
      use App\Http\Controllers\Controller;
      use Illuminate\Foundation\Auth\AuthenticatesUsers;
      
      // 下記を追記する
      use Illuminate\Http\Request;
      use Auth;
      // 上記までを追記する
      
      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 = '/home';
      
          /**
           * Create a new controller instance.
           *
           * @return void
           */
          public function __construct()
          {
              $this->middleware('guest')->except('logout');
              //下記を追記する
              $this->middleware('guest:admin')->except('logout');
          }
      
          // 下記を追記する
          public function showAdminLoginForm()
          {
              return view('auth.login', ['url' => 'admin']);
          }
      
          public function adminLogin(Request $request)
          {
              $this->validate($request, [
                  'email'   => 'required|email',
                  'password' => 'required|min:6'
              ]);
      
              if (Auth::guard('admin')->attempt(['email' => $request->email, 'password' => $request->password], $request->get('remember'))) {
      
                  return redirect()->intended('/admin');
              }
              return back()->withInput($request->only('email', 'remember'));
          }
          // 上記までを追記
      }
      
    4. 下記コマンドを実行してログインを司るコントローラファイルを開く。

      $ vi app/Http/Controllers/Auth/RegisterController.php
      
    5. 開いたコントローラファイルを下記の様に修正する。

      multi_auth_laravel_6/app/Http/Controllers/Auth/RegisterController.php
      <?php
      
      namespace App\Http\Controllers\Auth;
      
      //下記を追記する
      use App\Admin;
      use Illuminate\Http\Request;
      //上記までを追記する
      use App\User;
      use App\Http\Controllers\Controller;
      use Illuminate\Support\Facades\Hash;
      use Illuminate\Support\Facades\Validator;
      use Illuminate\Foundation\Auth\RegistersUsers;
      
      class RegisterController extends Controller
      {
          /*
          |--------------------------------------------------------------------------
          | Register Controller
          |--------------------------------------------------------------------------
          |
          | This controller handles the registration of new users as well as their
          | validation and creation. By default this controller uses a trait to
          | provide this functionality without requiring any additional code.
          |
          */
      
          use RegistersUsers;
      
          /**
           * Where to redirect users after registration.
           *
           * @var string
           */
          protected $redirectTo = '/home';
      
          /**
           * Create a new controller instance.
           *
           * @return void
           */
          public function __construct()
          {
              $this->middleware('guest');
              //下記を追記する
              $this->middleware('guest:admin');
          }
      
          /**
           * Get a validator for an incoming registration request.
           *
           * @param  array  $data
           * @return \Illuminate\Contracts\Validation\Validator
           */
          protected function validator(array $data)
          {
              return Validator::make($data, [
                  'name' => 'required|string|max:255',
                  'email' => 'required|string|email|max:255|unique:users',
                  'password' => 'required|string|min:6|confirmed',
              ]);
          }
      
          /**
           * Create a new user instance after a valid registration.
           *
           * @param  array  $data
           * @return \App\User
           */
          protected function create(array $data)
          {
              return User::create([
                  'name' => $data['name'],
                  'email' => $data['email'],
                  'password' => Hash::make($data['password']),
              ]);
          }
          //下記を追記する
          public function showAdminRegisterForm()
          {
              return view('auth.register', ['url' => 'admin']);
          }
      
          protected function createAdmin(Request $request)
          {
              $this->validator($request->all())->validate();
              $admin = Admin::create([
                  'name' => $request['name'],
                  'email' => $request['email'],
                  'password' => Hash::make($request['password']),
              ]);
              return redirect()->intended('login/admin');
          }
          //上記までを追記する
      }
      
  7. 管理者ログインページのビューファイルの修正

    1. 下記コマンドを実行してログインページのビューファイルを開く。

      $ vi resources/views/auth/login.blade.php
      
    2. 開いたビューファイルを下記の様に修正する。

      multi_auth_laravel_6/resources/views/auth/login.blade.php
      @extends('layouts.app')
      
      @section('content')
      <div class="container">
          <div class="row justify-content-center">
              <div class="col-md-8">
                  <div class="card">
                      <!-- 下記を修正する -->
                      <div class="card-header"> {{ isset($url) ? ucwords($url) : ""}} {{ __('Login') }}</div>
      
                      <div class="card-body">
                          @isset($url)
                          <form method="POST" action='{{ url("login/$url") }}' aria-label="{{ __('Login') }}">
                          @else
                          <form method="POST" action="{{ route('login') }}" aria-label="{{ __('Login') }}">
                          @endisset
                              @csrf
                              <!-- 上記までを修正する -->
      
                              <div class="form-group row">
                                  <label for="email" class="col-sm-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
      
                                  <div class="col-md-6">
                                      <input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required autofocus>
      
                                      @if ($errors->has('email'))
                                          <span class="invalid-feedback" role="alert">
                                              <strong>{{ $errors->first('email') }}</strong>
                                          </span>
                                      @endif
                                  </div>
                              </div>
      
                              <div class="form-group row">
                                  <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
      
                                  <div class="col-md-6">
                                      <input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required>
      
                                      @if ($errors->has('password'))
                                          <span class="invalid-feedback" role="alert">
                                              <strong>{{ $errors->first('password') }}</strong>
                                          </span>
                                      @endif
                                  </div>
                              </div>
      
                              <div class="form-group row">
                                  <div class="col-md-6 offset-md-4">
                                      <div class="form-check">
                                          <input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
      
                                          <label class="form-check-label" for="remember">
                                              {{ __('Remember Me') }}
                                          </label>
                                      </div>
                                  </div>
                              </div>
      
                              <div class="form-group row mb-0">
                                  <div class="col-md-8 offset-md-4">
                                      <button type="submit" class="btn btn-primary">
                                          {{ __('Login') }}
                                      </button>
      
                                      <a class="btn btn-link" href="{{ route('password.request') }}">
                                          {{ __('Forgot Your Password?') }}
                                      </a>
                                  </div>
                              </div>
                          </form>
                      </div>
                  </div>
              </div>
          </div>
      </div>
      @endsection
      
  8. 管理者登録ページのビューファイルの修正

    1. 下記コマンドを実行してログインページのビューファイルを開く。

      $ vi resources/views/auth/register.blade.php
      
    2. 開いたビューファイルを下記の様に修正する。

      multi_auth_laravel_6/resources/views/auth/register.blade.php
      @extends('layouts.app')
      
      @section('content')
      <div class="container">
          <div class="row justify-content-center">
              <div class="col-md-8">
                  <div class="card">
                      <!-- 下記を修正する -->
                      <div class="card-header"> {{ isset($url) ? ucwords($url) : ""}} {{ __('Register') }}</div>
      
                      <div class="card-body">
                          @isset($url)
                          <form method="POST" action='{{ url("register/$url") }}' aria-label="{{ __('Register') }}">
                          @else
                          <form method="POST" action="{{ route('register') }}" aria-label="{{ __('Register') }}">
                          @endisset
                              @csrf
                              <!-- 上記までを修正する -->
      
                              <div class="form-group row">
                                  <label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Name') }}</label>
      
                                  <div class="col-md-6">
                                      <input id="name" type="text" class="form-control{{ $errors->has('name') ? ' is-invalid' : '' }}" name="name" value="{{ old('name') }}" required autofocus>
      
                                      @if ($errors->has('name'))
                                          <span class="invalid-feedback" role="alert">
                                              <strong>{{ $errors->first('name') }}</strong>
                                          </span>
                                      @endif
                                  </div>
                              </div>
      
                              <div class="form-group row">
                                  <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
      
                                  <div class="col-md-6">
                                      <input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required>
      
                                      @if ($errors->has('email'))
                                          <span class="invalid-feedback" role="alert">
                                              <strong>{{ $errors->first('email') }}</strong>
                                          </span>
                                      @endif
                                  </div>
                              </div>
      
                              <div class="form-group row">
                                  <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
      
                                  <div class="col-md-6">
                                      <input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required>
      
                                      @if ($errors->has('password'))
                                          <span class="invalid-feedback" role="alert">
                                              <strong>{{ $errors->first('password') }}</strong>
                                          </span>
                                      @endif
                                  </div>
                              </div>
      
                              <div class="form-group row">
                                  <label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label>
      
                                  <div class="col-md-6">
                                      <input id="password-confirm" type="password" class="form-control" name="password_confirmation" required>
                                  </div>
                              </div>
      
                              <div class="form-group row mb-0">
                                  <div class="col-md-6 offset-md-4">
                                      <button type="submit" class="btn btn-primary">
                                          {{ __('Register') }}
                                      </button>
                                  </div>
                              </div>
                          </form>
                      </div>
                  </div>
              </div>
          </div>
      </div>
      @endsection
      
  9. 認証後遷移ページの作成

    1. 下記コマンドを実行してビューファイルを作成する。

      $ touch resources/views/layouts/auth.blade.php
      $ touch resources/views/admin.blade.php
      
    2. 下記コマンドを実行して先に作成したビューファイルを開く。

      $ vi resources/views/layouts/auth.blade.php
      
    3. 下記の内容をコピーアンドペーストで貼り付ける。

      multi_auth_laravel_6/resources/views/layouts/auth.blade.php
      <!DOCTYPE html>
      <html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
      <head>
          <meta charset="utf-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1">
      
          <!-- CSRF Token -->
          <meta name="csrf-token" content="{{ csrf_token() }}">
      
          <title>{{ config('app.name', 'Laravel') }}</title>
      
          <!-- Scripts -->
          <script src="{{ asset('js/app.js') }}" defer></script>
      
          <!-- Fonts -->
          <link rel="dns-prefetch" href="https://fonts.gstatic.com">
          <link href="https://fonts.googleapis.com/css?family=Raleway:300,400,600" rel="stylesheet" type="text/css">
      
          <!-- Styles -->
          <link href="{{ asset('css/app.css') }}" rel="stylesheet">
      </head>
      <body>
          <div id="app">
              <nav class="navbar navbar-expand-md navbar-light navbar-laravel">
                  <div class="container">
                      <a class="navbar-brand" href="{{ url('/') }}">
                          {{ config('app.name', 'Laravel') }}
                      </a>
                      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
                          <span class="navbar-toggler-icon"></span>
                      </button>
      
                      <div class="collapse navbar-collapse" id="navbarSupportedContent">
                          <!-- Left Side Of Navbar -->
                          <ul class="navbar-nav mr-auto">
      
                          </ul>
      
                          <!-- Right Side Of Navbar -->
                          <ul class="navbar-nav ml-auto">
                              <!-- Authentication Links -->
                             <li class="nav-item dropdown">
                                  <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
                                      Hi There <span class="caret"></span>
                                  </a>
      
                                  <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
                                      <a class="dropdown-item" href="{{ route('logout') }}"
                                         onclick="event.preventDefault();
                                                       document.getElementById('logout-form').submit();">
                                          {{ __('Logout') }}
                                      </a>
      
                                      <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
                                          @csrf
                                      </form>
                                  </div>
                              </li>
                          </ul>
                      </div>
                  </div>
              </nav>
      
              <main class="py-4">
                  @yield('content')
              </main>
          </div>
      </body>
      </html>
      
    4. 下記コマンドを実行して先に作成したビューファイルを開く。

      $ vi resources/views/admin.blade.php
      
    5. 下記の内容をコピーアンドペーストで貼り付ける。

      multi_auth_laravel_6/resources/views/admin.blade.php
      @extends('layouts.auth')
      
      @section('content')
      <div class="container">
          <div class="row justify-content-center">
              <div class="col-md-8">
                  <div class="card">
                      <div class="card-header">Dashboard</div>
      
                      <div class="card-body">
                          Hi boss!
                      </div>
                  </div>
              </div>
          </div>
      </div>
      @endsection
      
    6. 下記コマンドを実行して先に作成したビューファイルを開く。

      $ vi resources/views/layouts/home.blade.php
      
    7. すでに記載されている内容を削除し下記の内容をコピーアンドペーストで貼り付ける。

      multi_auth_laravel_6/resources/views/layouts/home.blade.php
      @extends('layouts.auth')
      
      @section('content')
      <div class="container">
          <div class="row justify-content-center">
              <div class="col-md-8">
                  <div class="card">
                      <div class="card-header">Dashboard</div>
      
                      <div class="card-body">
                           Hi there, regular user
                      </div>
                  </div>
              </div>
          </div>
      </div>
      @endsection
      
  10. ルーティングの記載と認証後遷移ページの設定と例外時の処理の記載

    1. 下記コマンドを実行してルーティングファイルを開く。

      $ vi routes/web.php
      
    2. 下記の様に追記する。

      multi_auth_laravel_6/routes/web.php
      <?php
      
      /*
      |--------------------------------------------------------------------------
      | 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!
      |
      */
      
      Route::get('/', function () {
          return view('welcome');
      });
      
      Auth::routes();
      
      Route::get('/home', 'HomeController@index')->name('home');
      
      //下記を追記する
      Route::get('/login/admin', 'Auth\LoginController@showAdminLoginForm');
      Route::get('/register/admin', 'Auth\RegisterController@showAdminRegisterForm');
      
      Route::post('/login/admin', 'Auth\LoginController@adminLogin');
      Route::post('/register/admin', 'Auth\RegisterController@createAdmin');
      
      Route::view('/home', 'home')->middleware('auth');
      Route::view('/admin', 'admin');
      //上記までを追記する
      
  11. リダイレクトの設定

    1. 下記コマンドを実行してリダイレクトを司るミドルウェアファイルを開く

      $ vi app/Http/Controllers/Middleware/RedirectIfAuthenticated.php
      
    2. 下記の様に修正する。

      multi_auth_laravel_6/app/Http/Controllers/Middleware/RedirectIfAuthenticated.php
      <?php
      
      namespace App\Http\Middleware;
      
      use Closure;
      use Illuminate\Support\Facades\Auth;
      
      class RedirectIfAuthenticated
      {
          public function handle($request, Closure $next, $guard = null)
          {
              // 下記を追記する
              if ($guard == "admin" && Auth::guard($guard)->check()) {
                  return redirect('/admin');
              }
              // 上記までを追記する
              if (Auth::guard($guard)->check()) {
                  return redirect('/home');
              }
      
              return $next($request);
          }
      }
      
  12. 例外時の設定

    1. 下記コマンドを実行してハンドラーファイルを開く。

      $ vi app/Exceptions/Handler.php
      
    2. 下記のようにハンドラーファイルを修正する。

      multi_auth_laravel_6/app/Exceptions/Handler.php
      <?php
      
      namespace App\Exceptions;
      
      use Exception;
      use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
      
      //下記を追記する
      use Illuminate\Auth\AuthenticationException;
      use Auth; 
      //上記までを追記する
      
      class Handler extends ExceptionHandler
      {
          /**
           * A list of the exception types that are not reported.
           *
           * @var array
           */
          protected $dontReport = [
              //
          ];
      
          /**
           * A list of the inputs that are never flashed for validation exceptions.
           *
           * @var array
           */
          protected $dontFlash = [
              'password',
              'password_confirmation',
          ];
      
          /**
           * Report or log an exception.
           *
           * @param  \Exception  $exception
           * @return void
           */
          public function report(Exception $exception)
          {
              parent::report($exception);
          }
      
          /**
           * Render an exception into an HTTP response.
           *
           * @param  \Illuminate\Http\Request  $request
           * @param  \Exception  $exception
           * @return \Illuminate\Http\Response
           */
          public function render($request, Exception $exception)
          {
              return parent::render($request, $exception);
          }
          //下記を追記する
          protected function unauthenticated($request, AuthenticationException $exception)
          {
              if ($request->expectsJson()) {
                  return response()->json(['error' => 'Unauthenticated.'], 401);
              }
              if ($request->is('admin') || $request->is('admin/*')) {
                  return redirect()->guest('/login/admin');
              }
              return redirect()->guest(route('login'));
          }
          //上記までを追記する
      
      }
      
  13. 確認

    1. 下記コマンドを実行してローカルサーバを起動する。

      $ php artisan serve
      
    2. 下記にアクセスしてLaravelの初期画面が表示されることを確認する。

    3. 下記にアクセスし必要情報を入力後「Registar」をクリックする。

    4. 下記の画面にリダイレクトすることを確認する。一つ前の手順で入力した管理者登録時の情報を入力し「Login」をクリックする。

      Laravel-10.png

    5. 下記のページ「Hi boss!」が表示されれば管理者としてのログインは完了である。

      Laravel.png

参考文献

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む