Laravel認証後,認証ユーザーである情報をどこで保持するのか.

Laravelの認証後に、認証ユーザーであることをどこで判別しているのか。
疑問を調べてみました。

認証の設定方法によって違いますが、
laravelのdefaultでは、Sessionに設定されているかと思います。

app > config > auth.php

下記のようにdriverがsessionで指定されていると思います。

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],   
    ],

sessionではどのような情報として保持されているのか?

実際にどのような情報として保持しているのかを確認してみます。

・確認用のControllerの作成

<?php
 namespace App\Http\Controllers;
 use Illuminate\Http\Request;
 class TestSessionController extends Controller
 {
     //
     public function index(Request $request)
     {
     $data = $request->session()->all();     dd($data);  }
 }

・確認用のRouteの作成

Route::get('test', [TestSessionController::class, 'index'])->name('index');

ログイン完了後.  /testへ遷移してみる。

dd()によって、下記の情報が確認できると思います。

下記の部分がAuthのguardのsession部分です。
{guard} 部分は、guardで設定し、ログインに利用したguardの文字列が含まれます。

array:4 [▼
   "login_{guard}_XXXXXXXXXXXXXXXXXXXXXXXXX" => 1
 ]

例えば、マルチログイン対応で、adminのguaradを作成し、adminでログインしている場合(認証されている場合)には、adminが入ります。

array:4 [▼
   "login_admin_XXXXXXXXXXXXXXXXXXXXXXXXX" => 1
 ]

User / Admin 複数のGuardでログインしている時

では、User、Admin複数のGuardでログインしている場合はどうなっているでしょうか。

同じく、/testへ遷移してみます。

"login_users_XXXXXXXXXXXXXXXXXXXXXXXXX" => 1
"login_admin_XXXXXXXXXXXXXXXXXXXXXXXXX" => 1

両方のguard, session情報が含まれていることがわかります。

ACM,ALB,Route53を活用してSSL化する.httpsのリダイレクトも.| AWS

標題の通りです。ご自身で取得したドメインをSSL化したい場合の一連の流れと作業を解説していきます。ちなみに、自分はお名前ドットコムでドメイン取得をしております。

■前提

・httpによるアクセスが出来ている環境であること.
・AWSを利用して、サーバー構築していること.

0:ACM,ALB,Route53各サービスの役割

初めに、各サービスの相互役割を解説して、全体の流れを解説していきたいと思います。

Route53の役割:

・ドメインのDNSレコードの作成
・ルーティング先をALBへ指定(ドメインアクセス後にALBへ)

ACMの役割:

・SSL化に必要な証明証の発行

ALBの役割:

・httpsアクセスに対して、ACMで発行した証明証を基にSSL化
・Target(今回はEC2インスタンス)へ、転送
・httpアクセスに対して、httpsへリダイレクト

①:ドメインの取得

ご自身でドメイン取得をして下さい。自分はお名前ドットコムでドメイン取得しております。

②:ACMで証明証発行

AWS Certificate Manager > 証明書 @ リクエスト

・「パブリック証明証をリクエスト」を選択
・完全修飾ドメイン名 (FQDN): {{ご自身で取得したドメインを指定}}

これで、証明証を発行します。

③:Route53レコードの設定

③-1:ホストゾーンの作成

Route 53 > ホストゾーン @ ホストゾーンの作成

・ドメイン名: {{ご自身で取得したドメインを指定}}
・パブリックホストゾーンを選択

これで、ホストゾーンを作成します。

③-2:NSレコードを、ドメイン購入サイトに反映

下記サイトなどで手順を参考に。

https://dev.classmethod.jp/articles/route53-domain-onamae/
https://blog.i-tale.jp/2020/04/13_02/

③-3:CNAMEレコードを、ACMからから作成

③-3-1:CNAMEレコードとは.

CNAMEは、ドメイン名と別ドメイン名をつけることができる。
つまり違うドメイン名で、同じ動きをしてくれます。

③-3-2:ACMから、Route53のCNAMEを作成

AWS Certificate Manager > 証明書 > ②で作成した証明証へ

Route53でレコード作成

③で作成している、Route53を選択して下さい。

④:ALBでSSL化 / ターゲットグループへの転送(EC2) / httpからのリダイレクト

④-1:ロードバランサーの作成

EC2 > ロードバランサー @ ロードバランサーの作成

Create Application Load Balancer

Basic configuration

名前を自由を設定にして、basic 情報を設定。

VPCを選択します。

今回のターゲットグループとなる、EC2インスタンスが設置してあるVPCを選択します。
※少なくとも2つ以上のアベイラビリティゾーンを追加して下さいとのことです。

リスナーを設定

・HTTPSプロトコル、443ポートで受けます。
・Forward to にターゲットグループを設定します。今回の場合は、EC2インスタンスを含まれるターゲットグループを指定
・secure listenerを From ACMで「②で作成したACMを指定」

セキュリティグループを設定

今回作成するセキュリティグループは、ALBへのセキュリティグループです。HTTPS・HTTPどちらもインバウンドを許可します。
※HTTPに対するリダイレクト処理は下記で紹介。

④-2:httpからのアクセスをhttpsへリダイレクト

設定方法を下記記事にて解説しています。

⑤:Route53で、Aレコードの設定

④で作成したALBを、Route53でAレコードをしていきます。

⑤-1:Aレコードとは.

ドメインをIPアドレスへ変換します。
ドメインへのリクエストが合った際のルート先を指定することができます。
今回はリクエストが合った際に、ALBを指定することで、SSL化を実行しています。

⑤-2:設定

・レコードタイプ:A
・エイリアス:オン
・ルーティング先:ALB >> ap-northeast-1(ご自身のリージョン)>>{{④で作成した、ALBを指定}}

Laravelリーレション先のデータ個数を集計 / hasMany

Laravelのeloquentは強力なORMです。

例えば、hasManyでリレーション先につながってデータの個数を集計して、オブジェクトへ返してくれる方法があります。

Modelでリレーション記述
    public function drinkNumber()
    {
        return $this->hasMany(Join::class, 'drink_id', 'id');
    }
modelからリレーション先を自動集計したデータをオブジェクトへ
    $drinks = Drink::withCount('drinkNumber')->where('status', 1)->get();

これで、$drinksの中には、Drink Modelのオブジェクトに加えて、集計したデータも一緒に含まれます。

カラム名は下記のルールで、名称付けられます。

リレーション名_count

ngrokを利用して、Line Messaging APIのWebhook検証を「成功」

LINE公式アカウントで、チャットボットを作成する際に必要になるWebhook。開発中でも、httpsでのレスポンスが求められるため開発中断してしまう方もいらっしゃるかもしれません。

前提:
今回は、Laravelを利用してwebhookの処理を実験していきます。
LaravelのInstallや、処理内容については説明を省略します。
pcはmacを利用しています。

ngrokを利用すれば、開発環境(ローカルPC)からでも、Webhookをhttpsで受け付けるエンドポイントを設定することが可能です。また、ランダムURLで問題なければ無料で利用でいることも魅力です。

①:ngrokとは

ngrokとは、ngrokで生成したURLにきたリクエストを、別のエンドポイントへ流してくれるサービスです。
今回の場合でいうと、ngrokで指定したURLにリクエストが合った場合に、ローカルホストのエンドポイントへ流してくれます。

ngrokのサービス: https://ngrok.com/

②:ngrokの設定

非常に簡単な設定で利用を開始できます。

ngrokにsign upして下さい。

https://dashboard.ngrok.com/get-started/setup

macの場合

②-1:Download ngrok

ローカルPCへ

②-2:Unzip to install

zipファイルを回答します。

unzip /path/to/ngrok.zip
②-3:Connect your account

authtokenを利用して、権限認証します。

ngrok authtoken {//自分のauthtoken}
②-4:Fire it up

ngrokの起動です。

ngrok http 80

これで、ターミナル上にngrokが立ち上がります。

②-5:ngrokでアクセス

Forwardingになっているアドレスが、利用可能なアドレスです。

③:webhookでレスポンスを返す処理を作成

Laravelで、ルーティングと、Postの処理を記述していきます。

③-1:ルーティング設定 web.php

// LINE メッセージ受信
Route::post('line/webhook', [LineWebhookController::class, 'webhook'])->name('line.webhook');

③-2:Controllerを設定 web.php

class LineWebhookController extends Controller
{
    public function webhook(Request $request) {
        return 'ok';
    }
}

Webhookが正常に起動するかを確認するための実験なので、Postの処理は一番簡単なレスポンスを記述

④:LineのWebhook設定にURLを適用

https://0a62-39-110-209-109.ngrok.io/line/webhook

上記のように設定します。

「検証」ボタンをおして、成功が返ってくれば成功です。

ngrokを利用して、Webhookのテストをすることが出来ました。

⑤:Line Webhookをngrokが利用出来ない??

https://www.line-community.me/en/question/5f07c0fb851f74ab9c18e8dc/ngrok%E3%81%A7%E5%A4%96%E9%83%A8%E5%85%AC%E9%96%8B%E3%81%97%E3%81%9Furl%E3%81%A7webhook%E6%A4%9C%E8%A8%BC%E3%82%92%E6%88%90%E5%8A%9F%E3%81%95%E3%81%9B%E3%81%9F%E3%81%84?sortby=newest

上記のようなコメントがありましたが、2022年4月時点で利用は出来ました!

HTTP ERROR 500|Laravelを初めて本番環境(EC2)に初アップ時の対応

EC2にgit cloneでLaravelのプロジェクトを移行、サーバーリクエストした際にHTTP ERROR 500が発生しました。

500エラーは様々な要因があるようです。下記を参考。

https://knowledge.cpi.ad.jp/other/281/

自分の場合は、非常に単純で、 .envファイルを作成していなかったから….

ファイルを作成すると、アクセスできました。( 別のディレクトリ権限のエラーが出ましたが )

Laravelのpost時に、URLをControllerへ送付する方法

laravelのget時にURLのパラメーターを送付することはよくあると思います。

では、Postの際はどのようにするのでしょうか??

まずは、データを引き渡すformから。

<form method="POST" action="{{ route('route名', ['param' => request()->path()] ) }}">
</form>

ポイント①:
actionのから変数を渡す方法です。
詳細はこちらを確認。LaravelでGET,POSTにパラメーターを追加して、渡す方法・受け取る方法

ポイント②:
現在のURLを取得する。今回でいう処理の 
request()->path() の部分です。

この2点から、パラメーターをControllerへ渡すことができすます。

Contollerでのパラメーターの受け取り方は、
$request->param で受け取ることが出来ます。
※param は、post の actionで指定したkeyになるので、変更可能です。

laravelライブラリ、GoodbyCSVで日本語文字化けを解消する方法

Goodby CSVの使い方に関しては、下記を参考にして進めています。

この中で、日本語が文字化けしてしまう現象が発生しました。

修正した部分は下記です。

// 元:$config->setFromCharset("sjis-win");
$config->setFromCharset("UTF-8"); //読み込んだcsvファイルの文字コード

問題はファイルの読み込む文字コードの問題でした。
PCのOSはmacです。この場合、UTF-8で読み込む必要がありました。
(Windowsの場合はsjis-winで問題ないと思います。)

laravel の仕組みと使い方

laravel7?? から、laravel, viewsの作り方が変わりました。

それまでは、@extends(”)・@section(”) などで、viewsを構築していたと思います。

基本的な考え方は、そこまで変化はありません。
より簡単に、使い回せるところは使いまわし、変数を上手く組み込む。といったところです。

どのように動いているのかが、理解出来ないと取っ付きづらいと思います。
今回は、どのような仕組みで動くのを最低限理解頂けたらと思います。

① viewsの配下で、blade作成するファイル

基本形は下記です。

// html ~~~~~~

ここがlaravelのプロジェクトの中で何を呼び出しているのかというと
<x-app-layout> → views/layout/app.blade.php を呼び出しています。

@extends('layouts.app') と同じような動きです。

では、<x-slot>は、どのように動くのでしょうか。

<x-slot></x-slot>範囲内に、反映したいhtmlデータを書きます。(もちろん、phpでも)

②views/layout/app.blade.php

では、<x-slot></x-slot>のデータは、どのように反映されるのでしょうか。

それが、views/layout/app.blade.phpの中で呼び出しております。

{{ $slot }}

という呼び出しで、<x-slot></x-slot>のデータを呼び出します。

なので、ベースとなるHTMLデータは、views/layout/app.blade.phpで
baldeファイルで変更したい部分は、{{ $slot }} で分けて反映させていく。といった仕組みです。

これも、以前の@section(”)と似たような考え方かと思います。

今回は、最初の一歩で取っつきにくい部分を解説しました。
様々な活用方法があるので、また解説していきたいと思います。

Laravelのスコープを利用して、Eloquentの処理を簡略化する方法

Laravelにスコープ(scope)という機能があります。
モデルを拡張する機能です。

使用用途は、特定のモデルで繰り返し発生しうる処理に対して、
モデル内でスコープを定義することで、スコープを呼び出すだけで済みます。

例えば、下記のようにPostモデルに対して、公開中の処理が下記の2つのwhere句を必要としましょう。毎回、公開中であるたびに、記述しているのはかなり面倒くさい。

Post::where(‘is_draft’, 0)
 ->where(‘isClosed’, 0) 

こういう、いろんなところで書きそうな条件はスコープにしてしまえば、書き間違えや書き漏れがなくなります。
https://readouble.com/laravel/7.x/ja/eloquent.html#query-scopes

ModelのPost.php の中で

    public function scopePublish($query)
{
return $query->where('is_draft', 0)
  ->where('isClosed', 0);
}
  • eloquentクラスに scopeXxxxxxでメソッドつくるとローカルスコープを作れる
  • そこに条件を書いておく

そうすると、呼び出し元では、

// 変更前
$searchArticles =  Post::where('is_draft', 0)
            ->where('isClosed', 0)
            ->where('lovesex' , $request->lovesex)// 変更後(スコープを利用)
$searchArticles =  Post::publish()
            ->where('lovesex' , $request->lovesex)
  • eloquentクラスに書いた scopeXxxxxxメソッドの Xxxxx 部分で呼び出し可能になる
// is_draft が0、かつ isClosed が0のデータ
RecomendArticle::where('is_draft', 0)
            ->where('isClosed', 0)

って読みづらかったものが

// 公開中のもの
Post::publish();

と無駄な記述も減らすことが可能です。

Laravelの認可を解説|Gateについて言及

認可とはどんな概念でしょうか。
認可とは、特定の行動に対しての権限の制御をする設定です。

認可には、Gate・Policy、2つの方法があります。

Gateで設定する場合

・App\Providers\ AuthServiceProvider に定義を記述
・認可したい箇所でGateファザードを用いて制御

Gateを App\Providers\ AuthServiceProvider で定義する

public function boot()の中で定義していきます。

Gateの名称を設定:chat-view
Gateが認可される条件を設定:if文の中がtrueの場合に返り値として return true;を返します。
※引数$userは、認証されているユーザー情報が入ってきます。

         Gate::define('chat-view', function (User $user, $chatRoom) {
            if ($chatRoom->apply_user_id === $user->id) {
                return true;
            }
        }); 

認可したい箇所でGateファザードを用いて制御

Gateを活用する場所では、下記のように扱います。
Gateファザードには、denies, allows , authorizeなどのメソッドがあります。
authorize で設定している下記では、Gateの定義した処理でtrueを返さない場合には403エラーを返します。

        $chatRoom = ChatRoom::findOrFail($chatRoomId);
        Gate::authorize('chat-view', $chatRoom);