CakePHPで開発してて、管理画面(admin)へのアクセスはIPで制限したいな
という場合の設定方法
昔、componentとか駆使して設定したことがありますが、もっと簡単な方法がありました。
htaccessを使う方法です。
/webroot/admin のディレクトを作ります。
そのadminディレクトリにhtaccessを置きます。
order deny,allow deny from all # 許可したいIP allow from 1.0.16.0
Webシステムに関することを中心に書いてます
CakePHPで開発してて、管理画面(admin)へのアクセスはIPで制限したいな
という場合の設定方法
昔、componentとか駆使して設定したことがありますが、もっと簡単な方法がありました。
htaccessを使う方法です。
/webroot/admin のディレクトを作ります。
そのadminディレクトリにhtaccessを置きます。
order deny,allow deny from all # 許可したいIP allow from 1.0.16.0
CakePHPで開発中、ある特定のURLの場合のみ404エラーが発生しました。
一意のURLを生成するためにbase64_encodeなどを駆使して生成したURLで発生。
色々調べてみると…
base64の使用文字
「a-zA-Z0-9+/」
この最後の「/」が問題のようだ。
urlencodeして使用していたけど×
mod_rewriteでURLに「%2F(スラッシュをurlencodeした文字)」が入っていると404を返すらしい。
それを解決するには、「AllowEncodedSlashes On」にすると解決できるそうだ。
これはデフォルトだとOffになっているため、先に%2Fをスラッシュとして認識し、URLが見つからないと404を返すと。。
んじゃ、Onにして解決だね!
と言いたいところだけど、それはちょっと難しい。
これはApacheの設置httpd.confなどで設定するものらしい。
htaccessでは解決できない。
レンタルサーバーなどでは簡単に変更できないので詰んでしまう・・・・
ということで、私は単純にqueryでgetとして送信することで回避させました。
https://zero-one-x.com/xxxx%2Fxxx
↓↓↓↓
CakePHP4のデバッグツールバーの表示方法
(CakePHP3も一緒なのかな??)
サーバーにアップしたところ、ツールバーが表示されなくなっていたので、その解決方法
まずはマニュアル通り設定をしていきます。
/config/bootstrap.php
下記のようなdebugの設定があります。
if (Configure::read('debug')) { Configure::write('Cache._cake_model_.duration', '+2 minutes'); Configure::write('Cache._cake_core_.duration', '+2 minutes'); // disable router cache during development Configure::write('Cache._cake_routes_.duration', '+2 seconds'); /** ここに追加します **/ }
「/** ここに追加します **/」に下記の2行を追加します。
// デバッグツールバーの表示 Configure::write('DebugKit.panels', ['DebugKit.Packages' => true]); Configure::write('DebugKit.safeTld', ['jp']);# jpドメインの表示を許可する
2行目のDebugKit.safeTldの値にご自身のドメインを指定します。
これでデバッグツールバーが画面の右下に表示されると思いますが、
それでも表示されない場合は強制的に表示させる設定を追加してみます。
Configure::write('DebugKit.forceEnable', true);
私の場合これでも表示されませんでした。
ソースを確認するとデバッグツールのタグを出力されていました。
コンソールを確認してみると下記のエラーメッセージが表示されてました。
toolbar.js?1678925804:54 Mixed Content:
The page at ‘https://xxxxxxxxxx.jp’ was loaded over HTTPS,
but requested an insecure frame ‘http://xxxxxxxxxx.jp/debug-kit/toolbar/xxxxx-xxxxx-xxxxx’.
This request has been blocked; the content must be served over HTTPS.
SSLじゃないのでブロックしたと。
この情報をもとに検索
下記の修正案がありました。
参考
https://github.com/cakephp/debug_kit/issues/736
上記の記事を参考に修正していきます。
vendor/cakephp/debug_kit/src/ToolbarService.php
public function injectScripts($row, ResponseInterface $response) { ... $url = Router::url('/', true); + if (isset($_SERVER['HTTPS']) || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') { + $url = str_replace('http', 'https', $url); + }
※「+」が追加する行
vendor/cakephp/debug_kit/templates/Requests/view.php
<?php $this->Html->script('DebugKit./js/debug_kit', [ 'block' => true, 'id' => '__debug_kit_app', 'data-id' => $toolbar->id, - 'data-url' => Router::url('/', true), + 'data-url' => checkHttps(Router::url('/', true)), 'data-webroot' => $this->request->getAttribute("webroot"), ]) ?> +<?php +function checkHttps($url) { + if (isset($_SERVER['HTTPS']) || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') { + $url = str_replace('http', 'https', $url); + } + return $url; +} ?>
※「+」が追加する行 「-」は削除する行
これで自ドメインがSSLならSSLでデバッグツールのURLを発行してくれます。
CakePHP4のバリデーションではまった話
バリデーションのalphaNumericが日本語をはじかないというので
preg_matchで実装しようとしたら動作しなくて困った
最初は下記のように書いたら「The provided value is invalid」のエラーが発生
$validator ->scalar('password') ->add('password', 'custom', [ 'rule' => function ($value) { return preg_match("/^[0-9a-zA-Z]{4,16}$/", $value); }, 'message' => '4桁以上16桁以下の英数字で入力してください。', ]);
色々調べてみると・・・
https://www.php.net/manual/ja/function.preg-match.php
preg_matchの戻り値
マッチした場合は1
マッチしなかった場合は0
失敗した場合はfalse
そう。マッチしない場合はfalseではない。
なので上記に書いたコードだと動作しない。
下記のように書き換えて動作確認できた!
$validator ->add('password', 'custom', [ 'rule' => function ($value) { $result = preg_match("/^[0-9a-zA-Z]{4,16}$/", $value); if($result == 1){ return true; } return false; }, 'message' => '4桁以上16桁以下の英数字で入力してください。', ]);
戻り値をifで判定してreturnでちゃんと戻す。
これで1日悩んでました。
データをダウンロード処理したときにフラグを立てるなど色々処理をしている。
ダウンロード後にリダイレクトかリロードをしたいと思った。
ダウンロードの処理でheaderを使っているのでリダイレクトのLocationが使えない。
そこでJSで別ウインドを開いて、そこにダウンロード処理を渡す。
その処理の後にページをリロードする処理をしてあげるとOK。
$(function(){ // ダウンロードボタン $('#order_export_btn').on('click', function() { window.open('<?= $this->Url->build(["controller" => "Hoge","action" => "download"], ['fullBase' => true]); ?>');// URLを開く setTimeout(reload, 1000);// 1秒後にリロード実行 }); }); // ページリロードの処理 var reload = function(){ location.reload(true); };
リダイレクトしたい場合はreloadのところをhrefにするとOK
// リダイレクトの処理 var reload = function(){ location.href = "https://zero-one-x.com/"; };
CakePHP3とかLaravelとか入れるにはComposerが必要になってきます。
XAMPP環境でもComposerが使えるようなのでその方法です。
まずはサイトからComposerをダウンロードしてインストールします。
https://getcomposer.org/download/
XAMPPのPHPの場所を指定。
C:\xampp\php\php.exe
※XAMPPポータブルだとこける可能性があるので、通常版を使うことをお勧めします。
プロキシの設定がある場合は、その設定を。
そのまま進めてインストール完了したらコマンドプロンプトで確認
>composer -V
バージョンが返ってこない場合はPCを再起動して試してみましょう。
それでもダメな場合は再インストールしてみてください。
CakePHP3でログイン認証を構築
細かいところは公式マニュアルをチェック
https://book.cakephp.org/3.0/ja/controllers/components/authentication.html
AppController.php – コントローラー全体の認証設定を行う
LoginController.php – ログインフォーム、ログイン処理など
TUsersController.php – ユーザー表示、登録、編集など
■認証設定(AppController.php)
initializeに認証処理を追記します。
public function initialize() { parent::initialize(); $this->loadComponent('RequestHandler'); $this->loadComponent('Flash'); # 認証 $this->loadComponent('Auth', [ 'loginAction' => [ 'controller' => 'Login', 'action' => 'index' ], 'loginRedirect' => [ 'controller' => 'TUsers', 'action' => 'index' ], 'logoutRedirect' => [ 'controller' => 'Login', 'action' => 'index' ], 'authenticate' => [ 'Form' => [ 'userModel' => 'TUsers', 'fields' => [ 'username' => 'account', 'password' => 'password' ] ] ] ]); }
loginAction – ログイン処理を行うコントローラーとアクションを指定
loginRedirect – ログイン後に移動するコントローラーとアクションを指定
logoutRedirect – ログアウト後に移動するコントローラーとアクションを指定
authenticate – 認証の詳細設定
Form:ユーザーID、パスワードを入力するフォームを作成して認証処理をさせるタイプ。他にはBasicやDigestがあります。
userModel:認証に使用するモデルを指定(デフォルトはUsers)
fields:認証に使用するカラムを指定(デフォルトはusernameとpassword)
■ログインフォーム(index.ctp)、認証処理(LoginController.php)
LoginController.php
public function initialize() { // AppControllerのAuthを継承 parent::initialize(); } // ログインフォームとログイン処理 public function index() { $this->loadModel("TUsers"); $users = $this->TUsers->newEntity(); if($this->request->is('post')) { $users = $this->TUsers->patchEntity($users, $this->request->data); $user = $this->Auth->identify(); if($user) { $this->Auth->setUser($user); $this->redirect($this->Auth->redirectUrl()); } else { echo "ログインエラーだよ"; } } }
index.ctp
<?= $this->Flash->render() ?> <?= $this->Form->create('Users') ?> User<?= $this->Form->text('account') ?> Password<?= $this->Form->password('password') ?> <?= $this->Form->button('login') ?> <?= $this->Form->end() ?>
■ユーザーの表示、追加、編集など
コントローラーに継承用の一文を追記します。
これがないとログイン後でもログインフォームに飛ばされちゃいます。
TUsersController.php
public function initialize(){ // AppControllerのAuthを継承 parent::initialize(); }
ユーザ作成、編集時にパスワードをハッシュ化させる。
Model/Entity/TUser.php
namespace App\Model\Entity; use Cake\ORM\Entity; use Cake\Auth\DefaultPasswordHasher;// ハッシャー class TUser extends Entity { protected function _setPassword($password){ if (strlen($password) > 0) { return (new DefaultPasswordHasher)->hash($password); } } }
こうやって書くと単純だけど結構苦戦しました。
AppControllerに書きましたけど、コントローラー単位でやる方法は分かりません(w
XAMPPでCakePHP3
ポータブルタイプだとパスの問題でなんかうまくいかない。
うちはUSBにポータブルタイプのXAMPPを入れてたのでそれにCakePHP3を入れようとしたけど駄目だった。
(各モジュールがあるのに読み込めないエラーが大量発生)
ということで別ドライブにXAMPPを入れてそこで実行
ブラウザからアクセスするとエラー
Fatal error: You must enable the intl extension to use CakePHP ~~~
PHPの設定でintlを使用する設定になっていないかも。
php.iniを開いて下記を修正
;extension=php_intl.dll
↓↓↓↓↓↓↓↓↓↓↓↓
extension=php_intl.dll
これでApachを再起動
これで直るかな。
タイムゾーン変更でエラー
config/app.php
config/bootstrap.php
上記のtimezoneを変更するとMySQLでエラーが発生
Error: SQLSTATE[HY000]: General error: 1298 Unknown or incorrect time zone: ‘Asia/Tokyo’
下記の公式サイトよりtimezoneのファイルをダウンロードします。
http://downloads.mysql.com/general/timezone_2016a_posix.zip
/xampp/mysql/data/mysql にファイルを上書きします。
その後MySQLを再起動
これでCakePHP3も動くようになったかな。