Github覚え書き

リモートリポジトリの設定

git remote add origin <GitHubで作成したリポジトリのURL>

 

ステージング用ブランチの作成

git branch stg

 

STGでプログラム変更→リモートのstgに反映>

git push origin stg

(visual code studio → [プッシュ先] - [origin]を選択)

 

<リモートの最新情報を取得>

git fetch

 

<Masterとstgとの差分を見る>

 プラグインgitlens」を入れる

 

<Masterとstgとをマージ>

ブランチをmasterに切り替えてから

git merge stg

 

 

 

 

===============-

remote レポジトリの確認

git remote -v

git remote -help

 

 

 

Laravelのメール送信にAmazon WorkMailを使うメモ

以外と探してもなかったので自分がやったことをメモ

.

.envに以下を設定

-----------------------------------

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mail.us-west-2.awsapps.com ←★リージョンによって異なる
MAIL_PORT=465
MAIL_FROM_ADDRESS=info@XXXX.com
MAIL_FROM_NAME=XXXX
MAIL_ENCRYPTION=ssl ←★sslにする
MAIL_USERNAME=info@XXX.com ←★WorkMailで設定したメアド
MAIL_PASSWORD=xxxxxxxx ←★WorkMailで設定したパスワード

-----------------------------------

 

※MAIL_HOSTのリージョンは以下に書いてある

us-west-2

smtp.mail.us-west-2.awsapps.com

us-east-1

smtp.mail.us-east-1.awsapps.com

eu-west-1

smtp.mail.eu-west-1.awsapps.com

docs.aws.amazon.com

 

※WorkMailの設定方法は以下がわかりやすい

qiita.com

 

以上

 

Laravelのメールの追加時にすることメモ

メールの初期設定は終わっていることが前提

 

1.artisanコマンドでmailableクラスを生成する

php artisan make:mail XXXMail

 

  以下にファイルが作成される

laravel
├ app
│ ├─ Mail
│ │ └─ XXXMail.php

 

2.作成したファイルに以下のような感じで記載

public function __construct($name, $body)
{
  $this->name = $name;
  $this->body = $body;
}


public function build()
{
  return $this
    ->subject('お問い合わせを承りました') 
    ->markdown('mailtemplate.contactmail') ←★使用するテンプレ
    ->with([
        'name' => $this->name,
        'body' => $this->body,
     ]);
}

 

3.コントローラーには以下のような感じで記載

use App\Mail\XXXMail;←★1で作成したクラス名
use Illuminate\Support\Facades\Mail;

 

$name = $request->name;
$body = $request->body;
$to = [
    [
     'name' => $request->name,
     'email' => $request->email
    ]
   ];
$cc = env('MAIL_FROM_ADDRESS');
Mail::to($to)
   ->send(new XXXMail($name, $body)); ←★2で作成したクラス

// 二重送信防止
$request->session()->regenerateToken();

return view('contact.complete');

 

 4.テンプレートは、/resources/views/ 2で書いた位置 に作成

@component('mail::message')
{{$name}}様   ←★2で->with()で渡した変数が使える

以下のお問い合わせを承りました。
回答までしばらくお待ちいただけますようお願い致します。

----------------------------------

{!! nl2br($body) !!}  ←★2で->with()で渡した変数が使える

----------------------------------

{{--@component('mail::button', ['url' => ''])

@endcomponent--}}

@endcomponent

 

以上

Laravelのvalidationのメモ

バリデーション 5.6 Laravel

①エラーがあると、前のページにリダイレクトさせたい場合

コントローラー側の基本形 

$request->validate([
  'id' => 'required|alpha_num',
]);

エラーがあると、前のページにリダイレクトする。その際、GETでリダイレクトされるため、前ページは、GETでアクセス可にしておく。

Route::get(....

 

View側の基本形 

<div class="{{ $errors->has('id') ? ' has-error' : '' }}">
  <input type="text" name="id" value="{{old('id', 初期値)}}">
  @if ($errors->has('bank_name'))
   <span class="help-block">
    <strong>{{ $errors->first('bank_name') }}</strong>
   </span>
  @endif
</div>

 

フォームを囲むDIVのclassに、

{{ $errors->has('id') ? ' has-error' : '' }}

 

を書いておくことで、エラーがあるとフォームに色をつけることができる。

フォームのvalueは、

{{old('id', 初期値)}}

 

としておくことで、エラーで戻ってきた際、元の入力値を受けることができる。

 

エラーメッセージ

laravel/resources/lang/ja/validation.phpに記載する

・属性を変える場合

'attributes'の中に属性のみ追記していく。 

'attributes' => [
  'id' => '会員ID',
],

・メッセージも変える場合

'custom'の中に追記していく。 

 'custom' => [
  'bank_name' => [
   'required' => '銀行名は必須です!',
  ],
],

 

ajaxでリクエストを送信した時は・・・

$request->validate([
]);

ajaxの場合、上記を書いておけば、エラーがあるとリダイレクトせず、バリデーションエラーを全部含んだJSONレスポンスが返される。

そして、ajax

$.ajax({
    type: "POST",
    dataType: "json",
    data: {},
    url: "{{ asset('xxxx') }}",
}).done(function(data){
}).fail(function(res){

    ※ここの部分

});

 fail()にレスポンスが返ってくる(422HTTPステータスで)。

 

確認画面から「戻る」ボタンを押した際、入力値を保存するには・・・ 

confirmのコントローラーに以下を記載

$request->flash();

「戻る」ボタンを押すと、

<form method="GET" action="{{ asset('元のURL') }}">

が実行されるようにしておく。

そうすると、元のページに戻った際、入力値が

{{old('id', 初期値)}}

で取得できている。

 

②エラーがあると、違うページにリダイレクトさせたい場合 

$validator = Validator::make($request->all(), [
  'id' => 'required|alpha_num',
]);
if ($validator->fails()) {
  return redirect('/error');
}

 

 

 

 

Laravelの管理画面について(Laravel-adminは止めたほうがいい)

「Laravel 管理画面」で検索すると上位に表示されるサイトに、

「Laravel-admin」がオススメ!とか書いてある。

 

それを信じて、「Laravel-admin」を入れてみたが、正直止めたほうがいい。

 

「Laravel-admin」は、どうも中国人が作ったようで、

コミュニティーが中国語がメインになっている。

 

ドキュメントがあるのだが、詳しいことが書いておらず、

コミュニティーを見ようと思ったが、中国語メインなので全く使えない。

 

DBを表示させるだけの管理画面であれば使えるかもしれないが、

ちょっと変わったことをしようとすると、途端にやり方がわからなくなる。

 

個人的な意見だが、2日間を無駄に費やした身として、Laravel-adminはオススメしない。

 

以上

 

PDFからPNGへの変換について

ImageMagickで変換する場合、元のPDFがCMYKで作成されていると、

どうやってもうまく行かなかった。(微妙に色が変わってしまう)

試したコマンドは以下のような感じ。

 

====いずれもうまく行かないので注意====

$exec="timeout 120 /usr/local/bin/convert -density 400 +profile -colorspace cmyk ".$originalPDF."[".$i."] -profile '".config('myconst.ROOTDIR')."resources/sRGB2014.icc' -colorspace sRGB ".$convertedPNG." 2>&1";

$exec="timeout 120 /usr/local/bin/convert -density 400 +profile -profile '".config('myconst.ROOTDIR')."resources/JapanColor2001Coated.icc' -colorspace cmyk -intent Relative -black-point-compensation -profile '".config('myconst.ROOTDIR')."resources/sRGB2014.icc' -colorspace sRGB ".$originalPDF."[".$i."] ".$convertedPNG." 2>&1";

 $exec="timeout 120 /usr/local/bin/convert -density 400 +profile -profile '".config('myconst.ROOTDIR')."resources/JapanColor2001Coated.icc' -colorspace cmyk -intent Relative -black-point-compensation ".$originalPDF."[0] ".$convertedPNG." 2>&1";

 $exec="timeout 120 /usr/local/bin/convert -density 400 -quality 1 +profile '*' -profile '".config('myconst.ROOTDIR')."resources/JapanColor2001Coated.icc' ".$originalPDF."[0] ".$convertedPNG." 2>&1";

$exec="timeout 120 /usr/local/bin/convert -density 400 ".$originalPDF."[0] +profile '*' -profile '".config('myconst.ROOTDIR')."resources/JapanColor2001Coated.icc' -profile '".config('myconst.ROOTDIR')."resources/sRGB_v4_ICC_preference.icc' ".$convertedJPG." 2>&1";

$exec="timeout 120 /usr/local/bin/convert -density 400 ".$originalPDF."[0] -profile '".config('myconst.ROOTDIR')."resources/sRGB_v4_ICC_preference.icc' ".$convertedJPG." 2>&1";

$exec="timeout 120 /usr/local/bin/convert -density 400 ".$originalPDF."[0] +profile '*' -profile '".config('myconst.ROOTDIR')."resources/JapanColor2001Coated.icc' PNG00:".$convertedPNG." 2>&1";

 

私の結論としては、元画像がCMYKの場合、ImageMagickではうまく行かない。

ImageMagickのバージョンは、Version: ImageMagick 7.0.7-25)

 

よって、XPDF(pdftocairo)を使う。

pdftocairo -png book.pdf test.png

 

まだ詳しくは見ていないが、CMYKでもいい感じで変換されている。

 

ImageMagick をLCMSに対応させる

ImageMagickを使ってPDFをPNGに変換していると以下のエラーが出ていた。

'convert: delegate library support not built-in \'
/var/www/xxx/book.pdf\' (LCMS) @ warning/profile.c/ProfileImage/836.'

 

ググるとどうやらLCMSというものを入れればいいらしい。

よって、入れてみる。

LCMSは以下にあった。

http://www.imagemagick.org/download/delegates/

 

sudo wget -P /usr/local/src http://www.imagemagick.org/download/delegates/lcms2-2.8.tar.gz

cd /usr/local/src

sudo tar -zxvf lcms2-2.8.tar.gz

cd lcms2-2.8

sudo ./configure --prefix=/usr/local

sudo make
sudo make install

 

※上記だけでいけるのかと思ったが、上記だけではImageMagickで使えるようにならなかった。

色々調べたが、『lcms2-devel』が必要だった。

これをyumで入れておく

sudo yum install lcms2-devel

 

ImageMagickを再コンパイルする

cd /usr/local/src/ImageMagick-7.0.7-25
sudo ./configure

sudo make clean
sudo make
sudo make install

 

■確認は以下のコマンド

convert -list configure | grep -i "delegates"

 DELEGATES mpeg jng jpeg lcms lzma png ps xml zlib

 

以上

 

Laravel でasset()やurl()が返すURLを『https』 にするためのメモ

https://readouble.com/laravel/5.5/ja/requests.html#configuring-trusted-proxies

App\Http\Middleware\TrustProxies を開き、

protected $proxies = '**';

にする。

これだけでOK!

Laravel5.6 へ Stripe.com の checkout を導入する

<前準備>

1.composer.jsonに以下を追記

"require": {
"php": ">=7.0.0",
"fideloper/proxy": "~3.3",
"laravel/framework": "5.5.*",
"laravel/tinker": "~1.0",
"laravelcollective/html": "^5.5",
"league/flysystem-aws-s3-v3": "~1.0",
"stripe/stripe-php": "6.*" ←☆ここを追記
},

 

2.SSHでlaravelのインストールディレクトリに移動し、以下を実行

$ composer update

 

3.vendorディレクトリの下に、「stripe」が出来ていればインストール成功

 

<プログラム>

https://stripe.com/docs/quickstart

 このページを見ると、Stripeには、大きく、

●Checkout

●Stripe.js and Elements

の2つの方法があることがわかる。

カスタマイズが必要な場合は、Stripe.jsを使うようだが、とりあえず、Checkoutで進める。

 

<決済画面の作成>

stripe.comのCheckoutのページをみると、以下のコードを貼ると、ポップアップで決済画面が表示されるとのことであった。

https://stripe.com/docs/checkout#integration-simple

<form action="your-server-side-code" method="POST">
  <script
    src="https://checkout.stripe.com/checkout.js" class="stripe-button"
    data-key="pk_test_******************"
    data-amount="999"
    data-name="Demo Site"
    data-description="Widget"
    data-image="https://stripe.com/img/documentation/checkout/marketplace.png"
    data-locale="auto"
    data-currency="jpy">
  </script>

 

しかし、何度やっても表示されない。

どうやら、Laraveのテンプレ(app.blade.php)に標準で入っている『app.js』

<script src="{{ asset('js/app.js') }}"></script>

があると、Stripeのコードが動かないことがわかった。

 

よって、【シンプル】コードは諦め、同じページにある【Custom】タブにあるコードを貼ると、うまくポップアップするようになった。

https://stripe.com/docs/checkout#integration-custom

<script src="https://checkout.stripe.com/checkout.js"></script>

<button id="customButton">Purchase</button>

<script>
var handler = StripeCheckout.configure({
  key: 'pk_test_***********************',
  image: 'https://stripe.com/img/documentation/checkout/marketplace.png',
  locale: 'auto',
  token: function(token) {
    // You can access the token ID with `token.id`.
    // Get the token ID to your server-side code for use.
  }
});

document.getElementById('customButton').addEventListener('click', function(e) {
  // Open Checkout with further options:
  handler.open({
    name: 'Demo Site',
    description: '2 widgets',
    currency: 'jpy',
    amount: 2000
  });
  e.preventDefault();
});

// Close Checkout on page navigation:
window.addEventListener('popstate', function() {
  handler.close();
});
</script>

 

上記サンプルプログラムでは、カード情報のトークン化完了後、決済処理に移る方法が書かれていない。そこで、トークンが返ってきた後、フォームをコントローラーに送信するために、以下のような感じにした。

【Viewのソース】(Formで遷移バージョン)

 
<form id="stripecharge" method="post"
action="{{ asset('orderexec') }}" class="form-horizontal">
{{ csrf_field() }}
 
<button id="customButton" class="stripe_button">注文画面</button>
<input type="hidden" id="stripeToken" name="stripeToken" />
<input type="hidden" id="stripeEmail" name="stripeEmail" />
<input type="hidden" id="stripeArgs" name="stripeArgs" />
</form>
 
<script>
var handler = StripeCheckout.configure({
key: '{{ env('STRIPE_PUB_KEY') }}',
currency: 'jpy',
locale: 'auto',
zipCode: true,
name: '{{ config('app.name', 'Laravel') }}',
description: '2 widgets',
billingAddress: true,
shippingAddress: true,
email: "{{ $email }}",
token: function(token, args) {
   $("#stripeToken").val(token.id);
   $("#stripeEmail").val(token.email);
   $("#stripeArgs").val(JSON.stringify(args));
   $("#stripecharge").submit();
}
});

$("#customButton").on('click', function(e) {
var final_price = $("#changed_total_cost").text();
final_price = final_price.replace(/\$/g, '').replace(/\,/g, '');
final_price = parseFloat(final_price);

// Open Checkout with further options:
handler.open({
   amount: final_price,
});
e.preventDefault();
});

// Close Checkout on page navigation:
window.addEventListener('popstate', function() {
handler.close();
});
</script>
 

 

決済金額は、オプションやら送料やらで変動するため、$("#customButton").on('click')の中で決済金額を決定した後、

handler.open({ })

の中で、amountを決定している。

https://stripe.com/docs/recipes/variable-amount-checkout

 

上記Formで遷移バージョンの場合、やってみるとわかるが、stripeからトークン処理が返ってきた後、$("#stripecharge").submit() でフォームをPOSTするのだが、その間の処理が微妙に長く(数秒)、ユーザーは「あれ?」と思ってしまう。

よって、ajaxで処理し、途中はローディング画像を流し、決済完了後はモーダル画面を表示させるようにした。

【(改良版)Viewのソース】(ajaxバージョン)

 
<button id="customButton" class="stripe_button">ご注文画面</button>
{{!! 決済完了後に表示させるモーダルウィンドウの準備!!}}
<div class="remodal" data-remodal-id="modal_ordercomp"
data-remodal-options="hashTracking:false, closeOnOutsideClick: true">
    <h1>ご注文完了!</h1>
    <p>ご注文が完了しました。</p>
<button data-remodal-action="close" class="remodal-close"></button>
</div>

<script>
var handler = StripeCheckout.configure({
key: '{{ env('STRIPE_PUB_KEY') }}',
currency: 'jpy',
locale: 'auto',
zipCode: true,
name: '{{ config('app.name', 'Laravel') }}',
description: '2 widgets',
billingAddress: true,
shippingAddress: true,
email: "{{ $email }}",
token: function(token, args) {
   $("#kurukuru").css('display','block');←☆ローディングの表示
   $.ajaxSetup({
      headers: {
         'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
      }
  });
   $.ajax({
      type: "POST",
      dataType: "text",
      data: {'stripeToken': token.id,
      'stripeEmail':token.email,
      'stripeArgs': JSON.stringify(args),
      },
       url: "{{ asset('mypage/mybooks/orderexec') }}",
   }).done(function(data){
      //決済完了後、モーダルウィンドウを表示させる
      //以下は、remodal.jsとの連携例。適当に変えてください。
      $('[data-remodal-id=modal_ordercomp]').remodal().open();
  }).fail(function(res){
      alert('通信エラーが発生しました。');
   });
}
});

$("#customButton").on('click', function(e) {
var final_price = $("#changed_total_cost").text();
final_price = final_price.replace(/\$/g, '').replace(/\,/g, '');
final_price = parseFloat(final_price);

// Open Checkout with further options:
handler.open({
   amount: final_price,
});
e.preventDefault();
});
 

 

 <コントローラー側のプログラム>

 コントローラーは人によってする処理が違うので最低限のプログラムだけ下に書いておく。

public function orderexec(Request $request)
{
try {
   Stripe::setApiKey(env('STRIPE_SECRET_KEY'));
   $token = $request->input('stripeToken');
   $stripeArgs = $request->input('stripeArgs');
   logger($stripeArgs);

   $customer = Customer::create([
      'email' => $request->stripeEmail,
      'source' => $token,
      'metadata' => ['user_id' => Auth::id()],
   ]);
   
   $charge = Charge::create([
      'customer' => $customer->id,//必須
      'amount' => 999,
      'currency' => 'jpy',
      'description' => 'Example charge',
      'metadata' => ['order_id' => 6735],
   ]);
}
catch (\Exception $ex) {
   return $ex->getMessage();
}
return;
}
 

 ポイントは以下の2点。

$customer = Customer::create([
      'email' => $request->stripeEmail,
      'source' => $token, ←★ここでStripeから帰ってきたトークンを指定
      'metadata' => ['user_id' => Auth::id()],
   ]);

$charge = Charge::create([
      'customer' => $customer->id,←★customerでトークンを使ったので、このように指定する。再度トークンを指定するとエラーになった。
      'amount' => 999,
      'currency' => 'jpy',
      'description' => 'Example charge',
      'metadata' => ['order_id' => 6735],
   ]);

 

以上、ご参考まで。

(おかしな点があればコメントいただければ助かります。)

Laravel 5.6 ログイン認証回数制限で、ユーザー名以外をキーにする方法

Laravelのログイン認証の回数制限は、デフォルトでは、『制限はユーザの名前/メールアドレスとIPアドレスで限定されます。』と書かれている。

認証 5.3 Laravel

独自認証でユーザー名以外をキーにした場合の認証回数制限の方法をメモしておく。

 

1.ログインに使用するコントローラーに、以下の赤字を追記する。

(認証回数制限なしのコントローラーの作成方法は以下の記事)

fushigi.hatenadiary.com

 

<?php


//namespace App\Http\Controllers\Auth; //コメントアウト
namespace App\Http\Controllers\ViewAuth; // 追加

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

use Illuminate\Http\Request;// 追加
use Illuminate\Support\Facades\Auth;// 追加
use Illuminate\Support\Str;//認証回数制限用に追加
 
use App\Viewer;//追加
use Validator;//追加

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 = '/viewer';//変更

/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
//$this->middleware('guest')->except('logout');
$this->middleware('guest:viewuser')->except('logout');//変更
}
 
//以下追加
protected function guard()
{
return Auth::guard('viewuser'); //config/auth.phpで追加したguardを指定
}

//初期アクセス時。または認証後のアクセス時
public function index($page_id)
//$page_idは、web.phpの中で、Route::get('viewer/{page_id}'
//として指定している変数
{
$ninsyou = 0;//認証フラグ
//そのページにパスワードがついているかどうかを調べる
$password = Viewer::where('page_id', $page_id)->first();

if ($password->password != NULL) {//パスワードありの場合
if (Auth::guard('viewuser')->check()) { //認証済みの場合の処理。
$user = Auth::guard('viewuser')->user();
//guard('viewuser')のため、viewerテーブルのレコードが返される。
if ($user->page_id == $page_id) {
$ninsyou = 1; //認証OK
} else {
//違うページで認証は通っていたが、このページでは認証が通っていない場合
$ninsyou = 0;
}
} else { //未認証の場合の処理
$ninsyou = 0;
}
} else {//パスワードがない場合、そのままビュー画面へいく
$ninsyou = 1; //認証OK
}

if ($ninsyou==1) {
$this->view($page_id);
} else {
//ログインページへリダイレクト
return redirect()->route('viewlogin', ['page_id' => $page_id]);
}
}

//認証ページの表示
//$requestは、認証失敗時にGETでついてくるpass_eroorを取るために必要。
//$page_idは、web.phpで指定している、Route::get('viewer/login/{page_id}'の部分。
public function showLoginForm(Request $request, $page_id)
{
//function authenticate()で認証に失敗すると、
//redirect()でpass_error=1が付いてくる。
$pass_error = $request->input('pass_error');
 
return view('viewer.viewerlogin',
['page_id'=>$page_id, 'pass_error'=>$pass_error]);
}

//自前の認証
public function authenticate(Request $request)
{
//validatorを指定しないとエラーになる
$validator = Validator::make($request->all(), [
'page_id' => 'required|unique:posts',
'password' => 'required',
]);

 
//認証回数制限ここから
if ($this->hasTooManyLoginAttempts($request)) {
logger('認証回数制限!');
return $this->sendLockoutResponse($request);
}
//認証回数制限ここまで
 
Auth::guard('viewuser');

$page_id = $request->input('page_id');
$password = $request->input('password');

if (Auth::guard('viewuser')
->attempt(['page_id' => $page_id, 'password' => $password])) {
logger('認証成功!');
//閲覧ページを表示
return redirect()->route('viewurl',['page_id' => $page_id]);
} else {
logger('認証失敗');
$this->incrementLoginAttempts($request);//認証回数制限用に追加
//ログインページに戻る
return redirect()->route('viewlogin', ['page_id' => $page_id, 'pass_error'=>1]);
}
}

//認証回数制限ここから
protected function throttleKey(Request $request)
{
//デフォルトではユーザー名で認証回数制限をチェックしていた。
//これをpage_idに変える
//return Str::lower($request->input($this->username())).'|'.$request->ip();
return Str::lower($request->input('page_id')).'|'.$request->ip();
}
//認証回数制限ここまで
public function view($page_id)
{
認証後の閲覧ページの処理;
}

}

Laravel 5.6 で、userテーブル以外で認証を行う

Laravelを使って、特定ページに認証をつけることにした。

パスワードを知っている人だけが、そのページに入ることができるように。

 

そのページは、DBのviewerというテーブルにパスワードを設定しており、

そのviewerテーブルを使って認証を行うようにした。

各ページ毎にパスワードが異なっており、あるページで認証が通っても、別のページでは認証が通らないようにする。

またパスワードがついていないページは、認証なしで見ることができる。

 

(参考)

Laravelで複数テーブルを使ったログイン認証を実装する - Qiita

 

1.config/auth.php 

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

'api' => [
'driver' => 'token',
'provider' => 'users',
],
//以下を追加
'viewuser' => [
'driver' => 'session',
'provider' => 'viewusers',
],
],
 
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
//以下を追加
'viewusers' => [
'driver' => 'eloquent',
'model' => App\Viewer::class,
],
],

※パスワードの再送は設定しないため、'passwords'は追加していない

 

2.web.php

URL遷移のイメージ

//初期アクセス http://hogehoge/viewer/XXXXXXXXXX
Route::get('viewer/{page_id}',
'ViewAuth\LoginController@index')->name('viewurl');
 
//パスワードが付いている場合、ログイン画面へ
Route::get('viewer/login/{page_id}',
'ViewAuth\LoginController@showLoginForm')->name('viewlogin');
 
//ログイン認証
Route::post('viewer/login',
'ViewAuth\LoginController@authenticate')->name('viewpostlogin');

 

※Laravelのページで分かりにくかったが、通常の認証では、ログイン認証は、コントローラ@login を使う。

しかし、独自認証を行う場合、コントローラ@authenticateとして、コントローラ内にatuthenticate()を書く。

認証 5.3 Laravel

 

3.app/Viewer.php

通常のモデルは、

class Viewer extends Model

となっているが、このままでは認証に使うことができない。

よって、認証に使うモデル(ここでは、Viewer)は、以下のようにする。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\User as Authenticatable;//認証用に追加

//class Viewer extends Model
class Viewer extends Authenticatable//User.phpに合わせて変更
{
protected $table = 'Viewer';
protected $fillable = [
'page_id',
'password',
・・・
・・・
];
protected $hidden = [
'password',
];
}

 

4.app/Http/Middleware/RedirectIfAuthenticated.php

認証が完了した場合、通所は所定のページにリダイレクトされるようになっている。

しかし、私の場合、リダイレクト処理はコントローラ内で書くようにしたかったため、以下のようにして、認証後のリダイレクトを止めるようにした。

public function handle($request, Closure $next, $guard = null)
{
//変更。オリジナルは以下。
//if (Auth::guard($guard)->check()) {
// return redirect('/home');
//}
if (Auth::guard($guard)->check()) {
if ($guard=='viewuser') { //ここを追加
//viewuserの認証時は、認証を通った後もリダイレクトしない
} else {
return redirect('/home');
}
}
  return $next($request);
}

 

5.app/Http/Controllers/ViewAuth/LoginController.php

参考にしてください。

<?php

//namespace App\Http\Controllers\Auth; //コメントアウト
namespace App\Http\Controllers\ViewAuth; // 追加

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

use Illuminate\Http\Request;// 追加
use Illuminate\Support\Facades\Auth;// 追加
use App\Viewer;//追加
use Validator;//追加

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 = '/viewer';//変更

/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
//$this->middleware('guest')->except('logout');
$this->middleware('guest:viewuser')->except('logout');//変更
}
 
//以下追加
protected function guard()
{
return Auth::guard('viewuser'); //config/auth.phpで追加したguardを指定
}

//初期アクセス時。または認証後のアクセス時
public function index($page_id)
//$page_idは、web.phpの中で、Route::get('viewer/{page_id}'
//として指定している変数
{
$ninsyou = 0;//認証フラグ
//そのページにパスワードがついているかどうかを調べる
$password = Viewer::where('page_id', $page_id)->first();

if ($password->password != NULL) {//パスワードありの場合
if (Auth::guard('viewuser')->check()) { //認証済みの場合の処理。
$user = Auth::guard('viewuser')->user();
//guard('viewuser')のため、viewerテーブルのレコードが返される。
if ($user->page_id == $page_id) {
$ninsyou = 1; //認証OK
} else {
//違うページで認証は通っていたが、このページでは認証が通っていない場合
$ninsyou = 0;
}
} else { //未認証の場合の処理
$ninsyou = 0;
}
} else {//パスワードがない場合、そのままビュー画面へいく
$ninsyou = 1; //認証OK
}

if ($ninsyou==1) {
$this->view($page_id);
} else {
//ログインページへリダイレクト
return redirect()->route('viewlogin', ['page_id' => $page_id]);
}
}

//認証ページの表示
//$requestは、認証失敗時にGETでついてくるpass_eroorを取るために必要。
//$page_idは、web.phpで指定している、Route::get('viewer/login/{page_id}'の部分。
public function showLoginForm(Request $request, $page_id)
{
//function authenticate()で認証に失敗すると、
//redirect()でpass_error=1が付いてくる。
$pass_error = $request->input('pass_error');
 
return view('viewer.viewerlogin',
['page_id'=>$page_id, 'pass_error'=>$pass_error]);
}

//自前の認証
public function authenticate(Request $request)
{
//validatorを指定しないとエラーになる
$validator = Validator::make($request->all(), [
'page_id' => 'required|unique:posts',
'password' => 'required',
]);

Auth::guard('viewuser');

$page_id = $request->input('page_id');
$password = $request->input('password');

if (Auth::guard('viewuser')
->attempt(['page_id' => $page_id, 'password' => $password])) {
logger('認証成功!');
//閲覧ページを表示
return redirect()->route('viewurl',['page_id' => $page_id]);
} else {
logger('認証失敗');
//ログインページに戻る
return redirect()->route('viewlogin', ['page_id' => $page_id, 'pass_error'=>1]);
}
}

public function view($page_id)
{
認証後の閲覧ページの処理;
}

}

 

以上、ご参考まで。