20210103のlaravelに関する記事は10件です。

【ギリ初心者向け】Laravel Docker AWS(EC2) Webアプリ(PHP)を0から簡単にデプロイする方法(無料)①

できるようになること(MacOS前提です。同じことやればWinでも大丈夫)

Webアプリ(PHP)をDockerで作成し、AWSでデプロイする工程をわかりやすく書いていく!!
プログラミングはできるようになったけど作ったものを世の中に出したいけどわからん!となった人向けです

①〜③の3部構成になります
①全体像と全体の流れ 目次みたいなもん
②Dockerを利用した理由とプロジェクト作成手順
③作成したプロジェクトをAWS(EC2インスタンス)にUPして世の中にだす!

※知らない単語等も詳しく説明するつもりだが。都度ググってくださいな!ググる力もエンジニアの力の一つらしいですわ。(プロが言ってた)

まずは全体像から

qiita-square
全体のイメージはこんな感じ。
これを作成すれば作成した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にアップするところまで
それでは②へGO

Qiita初投稿で読みづらい箇所や誤っている箇所などがあると思いますが、優しくコメントでご指摘いただけると幸いです。

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

laravel + vue.jsのファイルアップロードについて

この記事を書いたきっかけ

これから始めるvue.js実践入門(山田祥寛)のファイルアップロードの項目を見ていて、laravel+vueの時には同じ書き方だと動かないことに気づいたから。

vue.jsでは普通はどうするの?

test.vue
new 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.php
Route::post('/hello/fileupload', [HelloController::class, 'file']);
HelloController.php
class 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のファイルアップロード機能をつかっていないところ

等、通常のやり方でないところもあると思うのですが、一応一つのやり方のメモとして参考になればと存じます。ここまで読んでいただきありがとうございました。

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

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);

参考

Laravel サービスプロバイダーついに理解

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

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。

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

Laravelでサービスコンテナからサービスを取り出す方法まとめ

下記の通り。

$name = app()->make('serviceName');
$name = app('serviceName');
$name = resolve('serviceName');
$name = App::make('serviceName');

ちなみにサービスコンテナの中身はdd(app())としてbindingsから確認できるよ。

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

[Laravel] コントローラー→ビューの値渡し・view, redirect

概要

PHP歴3ヶ月、Laravel歴1ヶ月の初学者です。私が混乱した「コントローラーで処理した変数をビューへ渡す方法」や「viewやredirectの意味の違い」をまとめました。同じように頭を抱える初学者の方が一人でも減り、下記コードの赤枠部に関する悩みが少しでも解決できれば幸いです。
show.png

開発環境

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.php
public function view()
 {   
    $message = "viewの表示";
    return view('/page',compact("message"));
 }
public function view2()
 {   
    return view('/page');
 }
public function redirect()
 {   
    return redirect('/view');
 }
web.php
Route::get('/view','Controller@view');
Route::get('/view2','Controller@view2');
Route::get('/redirect','Controller@redirect');
page.blade.php
<h1>
    これは{{$message}}です。
</h1>

①URLで/viewを呼び出す

view.png
勿論、コントローラーから変数messageがviewへ渡されpageが表示される。

②URLで/view2を呼び出す

次のようなエラーが発生。
view2.png

Undefined variable: message (変数messageに値がないよ)
view2メソッドは変数messageをviewへ渡していないため、エラーが出力される。

③URLで/redirectを呼び出す。

view.png
redirectはweb.phpに記載されているルーティング情報が読み込まれるため、上記の例ではweb.phpのRoute::get('/view','Controller@view');が読み込まれる。これにより変数messageをviewへ渡すことができるためpageが表示される。

最後に

私はLaravelを初めて触った時にコントローラーの戻り値の理解にかなり苦しみました。
書籍やネット情報で調べましたが、書き方にかなり差があってごちゃごちゃになりました。。
初歩的な部分ではありますが、初学者の方の理解の助けになれればと思います。
viewやredirectに関してはもう少し深掘りして更新していきます。
(もしこの記事に誤りがありましたらご教授いただけると幸いです。)

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

Tinkerを使ってみYO!

はじめに

Laravelを学ぶ中でTinkerが便利だなと感じたので記事にしてみました!
TinkerはLaravel標準で使える対話型のコマンドラインツールで、「PHP/Laravelの関数を実行」「DBのレコード操作」などを行うことができます。今回はユーザデータを見たり消したりしてみようと思います。

目次

  1. Tinkerを起動
  2. ユーザデータ確認
  3. ユーザデータ削除
  4. まとめ

$ 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のレコード操作」などを行うことができます。使いこなせるように積極的に使用していきます。

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

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のレコード操作」などを行うことができます。使いこなせるように積極的に使用していきます。

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

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のレコード操作」などを行うことができます。使いこなせるように積極的に使用していきたいです。

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

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.php
private const GUEST_USER_EMAIL = 'guest@guest.com';

今回の実装では、このメールアドレス情報の文字列を利用して、
DBにゲストユーザーの登録情報があるかを探します。

LoginController.php
public 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箇所に設置しました。

・ヘッダーのナビゲーションバー(右上)
スクリーンショット 2021-01-02 21.21.55.png

・ログイン画面(右下)
スクリーンショット 2021-01-02 21.20.33.png

それでは実装に入ります。
以下のコードを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)で実装しましたので、簡単にその実装方法をご紹介したいと思います。

実装例

フロントエンド側の対策

スクリーンショット 2021-01-03 10.38.31.png

プロフィール編集画面にて、ゲストユーザーでログインしている時は
ユーザー名パスワードを編集できないようにしています。
これは、タグに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.php
private 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.php
public 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]);
}

以上で、ゲストログイン機能の実装は終了になります!
お疲れ様でした!

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