- 投稿日:2021-01-03T23:41:06+09:00
【ギリ初心者向け】Laravel Docker AWS(EC2) Webアプリ(PHP)を0から簡単にデプロイする方法(無料)①
できるようになること(MacOS前提です。同じことやればWinでも大丈夫)
Webアプリ(PHP)をDockerで作成し、AWSでデプロイする工程をわかりやすく書いていく!!
プログラミングはできるようになったけど作ったものを世の中に出したいけどわからん!となった人向けです①〜③の3部構成になります
①全体像と全体の流れ 目次みたいなもん
②Dockerを利用した理由とプロジェクト作成手順
③作成したプロジェクトをAWS(EC2インスタンス)にUPして世の中にだす!※知らない単語等も詳しく説明するつもりだが。都度ググってくださいな!ググる力もエンジニアの力の一つらしいですわ。(プロが言ってた)
まずは全体像から
全体のイメージはこんな感じ。
これを作成すれば作成したWebアプリを世の中に出せる!!0から世の中に出すまで順序(目次みたいなもんですわ)
1. DockerをPCにインストール
2. Project(ディレクトリを作成)
3. Projectの中でDockerを使って環境構築
- Webサーバー(nginx)をインストール
- アプリケーションサーバー(php:7.4-fpm)をインストール, PHPパッケージ管理ツール(Composer)インストール
- データベースサーバー(mysql)をインストール
- PHPを扱うフレームワーク(Laravel)をインストール4. ProjectをGithubにUP
5. ローカルの状態で自由自在にプログラミング!!
ここでLaravel(PHP)でプログラミングするよ!!6. できたものをGithubにUP
7. AWSに登録してEC2インスタンス(Ubuntu)を作成!!
8. EC2インスタンス(Ubuntu)の中に環境構築
- PHPをインストール
- Webサーバー(nginx)をインストール
- アプリケーションサーバー(php:7.4-fpm)をインストール, PHPパッケージ管理ツール(Composer)インストール
- データベースサーバー(mysql)をインストール
- PHPを扱うフレームワーク(Laravel)をインストール9. EC2インスタンス (Ubuntu)内のディレクトリにgit clone。Githubからプロジェクトを持ってくる!!
10. 該当URLにアクセスして表示!!デプロイ成功!
具体的にどうすればよいか??
疲れたので今回の記事ではこんな感じにします
次回はDockerを使った環境構築からGithubにアップするところまで
それでは②へGOQiita初投稿で読みづらい箇所や誤っている箇所などがあると思いますが、優しくコメントでご指摘いただけると幸いです。
- 投稿日:2021-01-03T21:58:27+09:00
laravel + vue.jsのファイルアップロードについて
この記事を書いたきっかけ
これから始めるvue.js実践入門(山田祥寛)のファイルアップロードの項目を見ていて、laravel+vueの時には同じ書き方だと動かないことに気づいたから。
vue.jsでは普通はどうするの?
test.vuenew Vue({ el: '#app', data: { message: '' }, methods: { onchange: function() { let that = this; let fl = this.$refs.upfile.files[0]; let data = new FormData(); data.append('upfile', fl, fl.name); fetch('upload.php', { method: 'POST', body: data, }) .then(function (response) { return response.text(); }) .then(function (text) { that.message = text; }) .catch(function (error) { window.alert('Error: ' + error.message); }); } } });(upload.phpは省略します。下にあるtest.blade.phpと内容は同じです。)
試したこと1
resources/js/app.jsと、resources/js/components/Mycomponents.vueに上記のファイルの内容を配置しupload.phpをcomponents配下にupload.phpを置いてみる(雑。)
結果:
fileupload後に、「No input file specified. file upload」のメッセージが返ってくる。(失敗)寄り道はこれくらいにして・・・・・・
myComponent.vue<form> <input ref="upfile" type="file" v-on:change="onchange3" /> <input type="hidden" name="_token" v-bind:value="csrf"> </form> <br /> <p>{{ message }}</p> <br /> <script> data: function () { return { csrf: document.head.querySelector('meta[name="csrf-token"]').content, }; }, methods: { onchange3: function() { let that = this; let fl = this.$refs.upfile.files[0]; let data = new FormData(); data.append('upfile', fl, fl.name); fetch('/hello/fileupload',{ method: 'POST', body: data, headers: {"X-Requested-With": "XMLHttpRequest", 'X-CSRF-TOKEN':this.csrf} }) .then(function(response){ return response.text(); }) .then(function(text){ that.message = text; }) .catch(function(error){ window.alert('Error:' + error.message3); }); } } </script>web.phpRoute::post('/hello/fileupload', [HelloController::class, 'file']);HelloController.phpclass HelloController extends Controller { public function file() { return view('hello.test'); } }test.blade.php<?php $error = false; if ($_FILES['upfile']['error'] !== UPLOAD_ERR_OK) { $error = true; } else { $src = $_FILES['upfile']['tmp_name']; $dest = mb_convert_encoding($_FILES['upfile']['name'], 'SJIS-WIN', 'UTF-8'); if (!move_uploaded_file($src, $dest)) { $error = true; } } if ($error) { header('HTTP/1.1 500 Internal Server Error'); print 'アップロードできませんでした。'; } else { print 'アップロード成功:'.$dest; } ?>index.blade.php<!doctype html> <html lang="ja"> <head> <title>Index</title> <link href="{{ mix('css/app.css') }}" rel="stylesheet" type="text/css"> <meta name="csrf-token" content="{{ csrf_token() }}"> </head> <body> <-- 以下省略 -->これでとりあえずは(?)うまくいっているように見えました。
・非同期処理でaxiosをつかっていないところ
・laravelのファイルアップロード機能をつかっていないところ等、通常のやり方でないところもあると思うのですが、一応一つのやり方のメモとして参考になればと存じます。ここまで読んでいただきありがとうございました。
- 投稿日:2021-01-03T21:56:21+09:00
Laravelのサービスプロバイダについて
Laravelのサービスプロバイダについて調べたことを簡単にまとめます。
サービスプロバイダとは?
サービスプロバイダとはサービスをサービスコンテナに登録するためのもの。
サービスコンテナについてはLaravelのサービスコンテナについて調べたことを簡単にまとめてみたでざっくりまとめてます。
サービスプロバイダを使って、サービスコンテナにサービスを登録する手順
サービスプロバイダーの作成
php artisan make:provider SampleServiceProvider実行するとapp\Providersの下にSampleServiceProvider.phpファイルが作成される。
中身は下記の通り。
class SampleServiceProvider extends ServiceProvider { public function register() { // } public function boot() { // } }registerメソッドはサービスコンテナにサービスを登録するための記述をする。
bootメソッドはすべてのサービスプロバイダーが読み込まれたあとに実行したいコードを記述する。registerメソッドに処理を追加
public function register() { app()->bind('testSample', function(){ return 'test'; }); //下記の記述でもOK。 $this->app->bind('testSample', function(){ return 'test'; }); }config/app.phpへ追加
'providers' => [ App\Providers\SampleServiceProvider::class, ]サービスを使う
$test = app()->make('testSample'); dd($test);参考
- 投稿日:2021-01-03T21:44:57+09:00
Laravelのサービスコンテナについて調べたことを簡単にまとめてみた
Laravelのサービスコンテナについて調べたことを簡単にまとめます。
そもそもサービスコンテナとは?
LaravelではDIコンテナをサービスコンテナと呼びます。
簡単にいうと、サービスを格納できる入れ物です。
そして、格納しているサービスを使うこと(インスタンス化)ができる。サービスとは、色々な機能(メール送信など)のこと。
クラスを入れておくものぐらいのイメージでも良いと思います。(たぶん)
サービスコンテナの使い方
()の箇所は省略可能です。
1.サービス化したいクラスを作る
2.(サービスプロバイダを作って app.php に登録する|AppServiceProviderを使う)
3.(registerにインスタンス化する方法を定義しておく)
4.(bootでサービス同士の依存関係を解決する)
5.(ファサードを定義して app.phpに登録する)
6.サービスコンテナにインスタンスを提供してもらう参照:第1回 もう怖くない DIだって知らなくていい こんなにカンタンだから今日から Laravelのサービスコンテナ を使ってみて!
要するに最低限の機能で使うなら、1と6だけでOK。
記述すると、次の通り。(引数にクラスを入れてあげるとインスタンス化できる。)$sampleobject = app()->make('App\SampleClass'); //new で書く場合 $sampleobject = new App\SampleClass;サービスコンテナはクラスの依存を解決するためのもの
今紹介したように、サービスコンテナは最低限の機能だけを利用するなら、超簡単。
でもこれだと「何のためにあるの?」ってことになりますよね。
結論から言うと『クラスの依存を解決するため』らしいです。
ちょっと難しい話ですが、要するにクラスに依存しているものを自動的に解決してくれるのがサービスコンテナとのこと。
これらによって、下記のメリットがあります。
(1)テスト時にはアプリケーションコードで生成されるインスタンスをテスト用にすり替えるといったことができたり、
(2)あるインスタンスはアプリケーション実行プロセスで一つだけ(シングルトン)にしたいので、2回目の生成時には前回生成したインスタンスを返すサービスコンテナへの登録方法
サービスコンテナへの登録方法は2つ。
①bindメソッド・singletonメソッドをコントローラーなどに記述する方法
②サービスプロバイダーを使用する方法ちなみにbindメソッドとかは下記のように使える。
app()->bind('myclass', Sample\MyClass::class); app()->singleton('myclass', Sample\MyClass::class);②の方法でやるなら、
・サービスプロバイダーの作成
・registerメソッド内に処理(インスタンスを返す)を追加
・config/app.phpのproviderに登録
この手順で登録すればOK。
- 投稿日:2021-01-03T18:33:17+09:00
Laravelでサービスコンテナからサービスを取り出す方法まとめ
下記の通り。
$name = app()->make('serviceName'); $name = app('serviceName'); $name = resolve('serviceName'); $name = App::make('serviceName');ちなみにサービスコンテナの中身は
dd(app())
としてbindings
から確認できるよ。
- 投稿日:2021-01-03T17:32:44+09:00
[Laravel] コントローラー→ビューの値渡し・view, redirect
概要
PHP歴3ヶ月、Laravel歴1ヶ月の初学者です。私が混乱した「コントローラーで処理した変数をビューへ渡す方法」や「viewやredirectの意味の違い」をまとめました。同じように頭を抱える初学者の方が一人でも減り、下記コードの赤枠部に関する悩みが少しでも解決できれば幸いです。
開発環境
PHP 7.2.34 / Laravel 6.20.5
コントローラーからビューへ値を渡す方法
①withメソッド
②view関数の第二引数に[ ]
③view関数の第二引数にcompact関数①withメソッド
記述方法:
view('ビューファイル名')->with(変数名, 引数);
渡す変数が1つの場合
Controller.php//渡す変数が1つの場合 public function withPattern() { $message = "Hello"; return view('test')->with('message',$message); } //渡す変数が複数の場合 (配列として記述。) public function withPattern2() { $message = "Hello"; $name = "John"; return view('test')->with([ 'message'=> $message, 'name' => $name, ]); }②viewの第二引数に[ ]
記述方法:
view('ビューファイル名', ['変数名' , 引数 ]);
Controller.php//渡す変数が1つの場合 public function SecondArgumentPattern() { $message = "Hello"; return view('test',['message',$message]); } //渡す変数が複数の場合 (配列として記述。) public function SecondArgumentPattern2() { $message = "Hello"; $name = "John"; return view('test',[ 'message' => $message, 'name' => $name, ]); }③view関数の第二引数にcompact関数
記述方法:
view('ビューファイル名', compact('変数名'));
Controller.php//渡す変数が1つの場合 public function CompactPattern(){ $message = "Hello"; return view('test',compact('message')); //渡す変数が複数の場合 (変数名をカンマで区切って記述。) public function CompactPattern2(){ $message = "Hello"; $name = "John"; return view('test',compact('message','name')); }ビューは{{変数名}}で①②③全て展開可能(変数が複数でも同様)
view.php<p> 日本語のこんにちは,英語では{{$message}}です // Hello </p>比較すると、変数名のみで記述ができるcompact関数で値を渡すこと方が可読性が良さそうです。特に変数が増えてきたときに顕著ですね。(これは私の考察です。)
参考:https://laraweb.net/knowledge/1345/
view()とredirect()の違い
viewとredirectの挙動について実際に検証しました。
様々なQiita記事を見ましたが、「これ本当?」と思われるものがあったので…view()はresouces->viewファイルを読みにいき、
redirect()はweb.phpのルーティング情報を読みにいくことが大きな違いのようです。
下記の処理をそれぞれ呼び出していきます。Controller.phppublic function view() { $message = "viewの表示"; return view('/page',compact("message")); } public function view2() { return view('/page'); } public function redirect() { return redirect('/view'); }web.phpRoute::get('/view','Controller@view'); Route::get('/view2','Controller@view2'); Route::get('/redirect','Controller@redirect');page.blade.php<h1> これは{{$message}}です。 </h1>①URLで
/view
を呼び出す
勿論、コントローラーから変数messageがviewへ渡されpageが表示される。②URLで
/view2
を呼び出す
Undefined variable: message
(変数messageに値がないよ)
view2メソッドは変数messageをviewへ渡していないため、エラーが出力される。③URLで
/redirect
を呼び出す。
redirectはweb.phpに記載されているルーティング情報が読み込まれるため、上記の例ではweb.phpのRoute::get('/view','Controller@view');
が読み込まれる。これにより変数messageをviewへ渡すことができるためpageが表示される。最後に
私はLaravelを初めて触った時にコントローラーの戻り値の理解にかなり苦しみました。
書籍やネット情報で調べましたが、書き方にかなり差があってごちゃごちゃになりました。。
初歩的な部分ではありますが、初学者の方の理解の助けになれればと思います。
viewやredirectに関してはもう少し深掘りして更新していきます。
(もしこの記事に誤りがありましたらご教授いただけると幸いです。)
- 投稿日:2021-01-03T14:41:25+09:00
Tinkerを使ってみYO!
はじめに
Laravelを学ぶ中でTinkerが便利だなと感じたので記事にしてみました!
TinkerはLaravel標準で使える対話型のコマンドラインツールで、「PHP/Laravelの関数を実行」「DBのレコード操作」などを行うことができます。今回はユーザデータを見たり消したりしてみようと思います。目次
$ php artisan tinker
dockerの場合は、docker-compose.ymlファイルある場所で下記コマンド実行
$ docker-compose exec コンテナ名 php artisan tinker
を実行すると下記のような表示がされ、対話的にコマンドを実行することができます。
>>>使用できるコマンドを確認できます。
>>> help次はユーザーモデル全件を確認
>>> App\User::all();Userクラスを使っていますが、クラスを使う場合はApp\Userといったように名前空間も記述するようにしてください。
名前空間とは、app/User.phpのnamespaceの後に記述されている部分です。
└──laravel
└── app
└── User.phpちなみにこのappディレクトリはアプリケーションのコアとなるコードを含む重要なディレクトリです。
アプリケーション内のクラスのほとんどはこの中に設置されます。このメソッドは下記のようにコレクション(Illuminate\Database\Eloquent\Collection)が帰ってきました。このようにメソッドが配列を返すか、コレクションを返すかといったことも確認できます。
your.terminal=> Illuminate\Database\Eloquent\Collection {#3053 all: [ App\User {#3978 id: 1, name: "hoge", email: "hoge@example.com", email_verified_at: null, created_at: "2021-01-03 23:10:40", updated_at: "2021-01-03 23:10:40", }, ], }なお、App\Userを確認していただくとわかりますが、passwordやremember_tokenといったプロパティがあるのに、それらが表示されていません。(Userモデルで表示しない指定がされているため)
ユーザーモデルを削除
次にhogeというユーザーが不要なので、これを削除します。ユーザーhogeのidは1であるので、以下のコードを実行してください。
your.terminal>>> App\User::destroy(1);
=> 1
といったように削除件数が表示されれば削除は成功です。TinkerはLaravel標準で使える対話型のコマンドラインツールで、「PHP/Laravelの関数を実行」「DBのレコード操作」などを行うことができます。使いこなせるように積極的に使用していきます。
- 投稿日:2021-01-03T14:41:25+09:00
Tinkerでデータ操作してみました
はじめに
Laravelを学ぶ中でTinkerが便利だなと感じたので記事にしてみました!
TinkerはLaravel標準で使える対話型のコマンドラインツールで、「PHP/Laravelの関数を実行」「DBのレコード操作」などを行うことができます。今回はユーザデータを見たり消したりしてみようと思います。Tinkerを起動
$ php artisan tinker
dockerの場合は、docker-compose.ymlファイルある場所で下記コマンド実行
$ docker-compose exec コンテナ名 php artisan tinker
を実行すると下記のような表示がされ、対話的にコマンドを実行できます。
>>>下記コマンド(help)で使用できるコマンドを確認できます。
>>> helpユーザーモデル全件を確認
>>> App\User::all();Userクラスを使っていますが、クラスを使う場合はApp\Userといったように名前空間も記述するようにしてください。
名前空間とは、
app/User.phpのnamespace
の後に記述されている部分です。└──laravel
└── app
└── User.phpちなみにこのappディレクトリはアプリケーションのコアとなるコードを含む重要なディレクトリです。
アプリケーション内のクラスのほとんどはこの中に設置されます。この all() メソッドからは下記のようにコレクション(Illuminate\Database\Eloquent\Collection)が帰ってきました。このようにメソッドがどんな値を返すか、配列かコレクションかといったようなことも確認できます。
your.terminal=> Illuminate\Database\Eloquent\Collection {#3053 all: [ App\User {#3978 id: 1, name: "hoge", email: "hoge@example.com", email_verified_at: null, created_at: "2021-01-03 23:10:40", updated_at: "2021-01-03 23:10:40", }, ], }なお、App\Userを確認していただくとわかりますが、passwordやremember_tokenといったプロパティがあるのに、それらが表示されていません。(Userモデルで表示しない指定がされているため)
ユーザーモデルを削除
次にhogeというユーザーが不要なので、これを削除します。
ユーザーhogeのidは1であるので、以下のコードを実行してください。
your.terminal>>> App\User::destroy(1);
=> 1
といったように削除件数が表示されれば削除は成功です。まとめ
TinkerはLaravel標準で使える対話型のコマンドラインツールで、「PHP/Laravelの関数を実行」「DBのレコード操作」などを行うことができます。使いこなせるように積極的に使用していきます。
- 投稿日:2021-01-03T14:41:25+09:00
Tinkerでデータ操作
はじめに
Laravelを学ぶ中でTinkerが便利だなと感じたので記事にしてみました!
TinkerはLaravel標準で使える対話型のコマンドラインツールで、「PHP/Laravelの関数を実行」「DBのレコード操作」などを行うことができます。今回はユーザデータを見たり消したりしてみようと思います。Tinkerを起動
$ php artisan tinker
dockerの場合は、docker-compose.ymlファイルある場所で下記コマンド実行
$ docker-compose exec コンテナ名 php artisan tinker
を実行すると下記のような表示がされ、対話的にコマンドを実行できます。
>>>下記コマンド(help)で使用できるコマンドを確認できます。
>>> helpユーザーデータ全件を確認
>>> App\User::all();Userクラスを使っていますが、クラスを使う場合はApp\Userといったように名前空間も記述するようにしてください。
名前空間とは、
app/User.phpのnamespace
の後に記述されている部分です。└──laravel
└── app
└── User.phpちなみにこのappディレクトリはアプリケーションのコアとなるコードを含む重要なディレクトリです。
アプリケーション内のクラスのほとんどはこの中に設置されます。この all() メソッドからは下記のようにコレクション(Illuminate\Database\Eloquent\Collection)が帰ってきました。このようにメソッドがどんな値を返すか、配列かコレクションかといったようなことも確認できます。
your.terminal=> Illuminate\Database\Eloquent\Collection {#3053 all: [ App\User {#3978 id: 1, name: "hoge", email: "hoge@example.com", email_verified_at: null, created_at: "2021-01-03 23:10:40", updated_at: "2021-01-03 23:10:40", }, ], }なお、App\Userを確認していただくとわかりますが、passwordやremember_tokenといったプロパティがあるのに、それらが表示されていません。(Userモデルで表示しない指定がされているため)
ユーザーデータを削除
次にhogeというユーザーが不要なので、これをデータベースから削除します。
ユーザーhogeのidは1であるので、以下のコードを実行してください。
your.terminal>>> App\User::destroy(1);
=> 1
といったように削除件数が表示されれば削除は成功です。まとめ
今回は初歩的な操作としてユーザデータを見たり消したりしました。
TinkerはLaravel標準で使える対話型のコマンドラインツールで、「PHP/Laravelの関数を実行」「DBのレコード操作」などを行うことができます。使いこなせるように積極的に使用していきたいです。
- 投稿日:2021-01-03T11:34:18+09:00
Laravel6系でゲストログイン機能(かんたんログイン)の実装
はじめに
本記事では、ログイン時に
ユーザー名
やパスワード
を入力しなくても、
ワンクリックでゲストユーザーとしてログインできる「ゲストログイン機能」の実装方法をご紹介します。転職活動用のポートフォリオ等にゲストログイン機能があると
多忙な採用担当の方の負担が減り、アプリを利用してもらえる確率が高まりますよ!事前準備
ゲストログイン機能の実装の前に、以下が予め準備されていることが前提となります。
①ログイン機能の実装されている
②ゲストログイン用のユーザー(ゲストユーザー)の登録されている
→ 例)ユーザー名:ゲストユーザー
メールアドレス:guest@guest.com
③DBにusersテーブルがあり、passwordカラムが定義されている
④Userモデルが作成されている実装内容
ログイン機能とゲストユーザーの準備ができたら、いよいよ実装に入ります。
ご紹介する実装内容は割と簡単で、以下になります。
ゲストログインの処理を記述(Controller)
ルーティングの設定(web.php等)
ログイン画面等、任意のページにゲストログイン用のリンクを設置する(View)
補足)ユーザープロフィール編集機能の制限
ゲストログインの処理を記述(Controller)
まず今回は、Laravel6系をインストールしたら初めから存在する
app/Http/Controllers/Auth/LoginController.php
に、ゲストログインの処理を書いていきます。LoginController.php<?php namespace App\Http\Controllers\Auth; use App\Models\User; //※ ModelsディレクトリにUser.phpがある場合 use Illuminate\Support\Facades\Auth; # 〜〜〜〜〜〜〜 略 〜〜〜〜〜〜〜 class LoginController extends Controller { # 〜〜〜〜〜〜〜 略 〜〜〜〜〜〜〜 // ゲストユーザー用のメールアドレスを定数として定義 private const GUEST_USER_EMAIL = 'guest@guest.com'; // ゲストログイン処理 public function guestLogin() { $user = User::where('email', self::GUEST_USER_EMAIL)->first(); if ($user) { Auth::login($user); return redirect('/'); } return redirect('/'); } }解説〜
まず、以下のようにゲストユーザー用のメールアドレス
'guest@guest.com'
を定数として定義しています。LoginController.phpprivate const GUEST_USER_EMAIL = 'guest@guest.com';今回の実装では、このメールアドレス情報の文字列を利用して、
DBにゲストユーザーの登録情報があるかを探します。LoginController.phppublic function guestLogin() { $user = User::where('email', self::GUEST_USER_EMAIL)->first(); if ($user) { Auth::login($user); return redirect('/'); }処理の流れとしては、
「もしメールアドレスが'guest@guest.com'
であるユーザー(ゲストユーザー)がDBに存在すれば、そのユーザーでログインをしてトップページ('/')
にリダイレクトする」
ようになっています。ルーティングの設定(web.php等)
次に、今回は
routes/web.php
を編集して、ゲストログイン機能用のルーティングを設定します。
以下を追記してください。web.php# ゲストユーザーログイン Route::get('guest', 'Auth\LoginController@guestLogin')->name('login.guest');任意のページにゲストログイン用のリンクを設置する(View)
続いて、ゲストログイン処理をブラウザから実行できるように「ゲスト
ログイン」ボタンをViewに追加します。ボタンをお好みの場所に設置していきましょう。
ちなみに私は、自作アプリには以下のように
ヘッダーと、ログイン画面の2箇所に設置しました。それでは実装に入ります。
以下のコードをView(Blade)の任意の場所に追記してください。(デザインはBootstrap使用)<button class="btn btn-success"> <a href="{{ route('login.guest') }}" class="text-white"> ゲストログイン </a> </button>リンク先の
route('login.guest')
は、先ほどweb.phpでルーティングを設定した
name('login.guest')
とリンクしています。
また、< button >タグや< a >タグ内のclassには、Bootstrapのデザインを使用しています。
この辺については、お好みで調整してください。〜〜〜〜〜〜〜〜〜〜〜
ここまで実装できたら、ゲストログイン機能の実装自体は完了です!
実際に「ゲストログイン」ボタンをクリックして、ゲストユーザーとしてログインできているか確認してみましょう!ゲストユーザーのプロフィール編集を制限する
最後に、セキュリティ的な対策です。
もしあなたの開発しているアプリに、ユーザーの名前
やメールアドレス
等を編集できる
「ユーザープロフィール編集機能」がある場合、
ゲストユーザーのメールアドレスは変更できないようにしてください。もし誰かにゲストユーザーのメールアドレスを変更されてしまった場合、ゲストログイン機能が動かなくなってしまいます^^;
そのため、以下のような対策を取る必要があります
(A)メールアドレスの変更の際に、パスワードを求める仕様にする
(B)ゲストユーザーでログイン時はメールアドレスを変更できない仕様にする
(C)そもそもどのユーザーでもメールアドレスは変更できない仕様にする
私の場合、(B)で実装しましたので、簡単にその実装方法をご紹介したいと思います。
実装例
フロントエンド側の対策
プロフィール編集画面にて、ゲストユーザーでログインしている時は
ユーザー名
とパスワード
を編集できないようにしています。
これは、タグにreadonly属性
を追加することで実現できます。実装例
@if (Auth::user()->email == 'guest@guest.com') <p class="text-danger">※ゲストユーザーは、ユーザー名とメールアドレスを編集できません。</p> @endif <div class="form-group"> <label for="name"> ユーザー名 <small class="blue-grey-text">(15文字以内)</small> </label> @if (Auth::user()->email == 'guest@guest.com') <input class="form-control" type="text" id="name" name="name" value="{{ $user->name }}" readonly> @else <input class="form-control" type="text" id="name" name="name" value="{{ $user->name ?? old('name') }}"> @endif </div> <div class="form-group"> <label for="email">メールアドレス</label> @if (Auth::user()->email == 'guest@guest.com') <input class="form-control" type="text" id="email" name="email" value="{{ $user->email }}" readonly> @else <input class="form-control" type="text" id="email" name="email" value="{{ $user->email ?? old('email') }}"> @endif </div>上記のコードでは、
@if (Auth::user()->email == 'guest@guest.com')でゲストユーザーでログインしているかを判定し、もしゲストユーザーでログインしている場合には
< input >タグにreadonly属性
を付与するようにしています。
また、デザインにはBootstrapを使用しています。ただし、この実装だけでは重大な欠点がありまして、Chrome等のデペロッパーツールを使用して
readonly属性
を消されると簡単にメールアドレスを入力できてしまい、上書きされてしまいます。
なのでバックエンド側での対策も必要になってきます。バックエンド側の対策
私の場合、ユーザープロフィール編集機能の実装には以下の2つを作成しています。
・UserController.php
・UserRequest.php(フォームリクエストによるバリデーション)実装の手順としては、次の2つです。
①User.Request側:ゲストユーザーがログインしている場合は、
ユーザー名
とメールアドレス
をバリデーションにかけないようにする
②UserController側:バリデーションにかけた値だけをDBに保存するようにするこれで、ゲストユーザーのプロフィール編集ができないようになります。
実装例
UserRequest.phpprivate const GUEST_USER_EMAIL = 'guest@guest.com'; public function rules() { // ゲストユーザーログイン時は、ユーザー名とメールアドレスをバリデーションにかけない if (Auth::user()->email == self::GUEST_USER_EMAIL) { return [ 'profile_image' => 'file|mimes:jpeg,png,jpg,bmb|max:2048', 'self_introduction' => 'string|max:200|nullable', ]; } else { // ゲストユーザー以外がログインしている時は、全てのユーザー情報をバリデーションにかける return [ 'name' => 'required|string|max:15|', 'email' => 'required|string|email|max:255|', 'profile_image' => 'file|mimes:jpeg,png,jpg,bmb|max:2048', 'self_introduction' => 'string|max:200|nullable', ]; } }UserController.phppublic function update(UserRequest $request, string $name) { $user = User::where('name', $name)->first(); // バリデーションにかけた値だけをDBに保存 $user->fill($request->validated())->save(); return redirect()->route('users.show',['name' => $user->name]); }以上で、ゲストログイン機能の実装は終了になります!
お疲れ様でした!