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
↓↓↓↓
ページを作成してChromeで確認すると「このページを翻訳しますか?」と中国語→日本語の案内が出てきました。
サイトは日本語で作成しているけどな・・・なぜ?
色々調べてみると「漢字が多いと中国語と判定されることがある」という情報がありました。
対処するためのタグもありましたので、それを紹介します。
まずはlang属性の追加
<html lang="ja">
次にmetaタグ
<meta http-equiv="content-language" content="ja">
Googleの公式は「lang属性は見てないよ」って発表しているそうですが、
上記に対応でlang=jaの設定をしないと「検出されない言語」という表記で翻訳の画面は表示されました。
それで翻訳の画面を表示させないためには両方の設定が必要なようです。
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を発行してくれます。
PHPで次月や前月を抽出するときに注意するべき点。
私は下記の方法で処理してました。
■次月を出力
date("n", strtotime("+1 month"))
上記方法だと特定の日で予想と違う結果が返ってくる
1/30、1/31に処理を見ると結果は「3月」になってしまう。
「2月」が返ってきてほしいが…
1/30に見ると処理は今日の日付の”月”に+1するので「2/30」→「3/1」となり、
結果は「3月」となってしまう。
これを回避するために下記の処理にすること
date('n', strtotime(date("Y-m-01") . ' +1 month'))
しっかりと「01」と指定してあげることで回避できる。
$this->Auth->identify();
上記を使うと送信されたデータとDBから抽出したデータをチェックするのを自動でやってくれます。
手動でやりたい場合は上記は使えません。
下記のコードで手動でチェックできます。
use Cake\Auth\DefaultPasswordHasher; $hasher = new DefaultPasswordHasher(); // パスワードチェック if($hasher->check('素のパスワード', 'ハッシュ化されたパスワード')){ // パスワードOKの処理 }else{ // パスワードNGの処理 }
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日悩んでました。
2021年8月13日から変更になった仕様
アカウント、パスワードの廃止問題の解決方法
私はSourcetreeしか使ってませんが・・・
プッシュしようとすると下記のようなエラーが発生。
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
まずはGitHubでアクセストークンをゲットします。
https://github.com/
ログイン後、右上のアイコンから「Settings」へ
「Developer settings」へ移動
「Personal access tokens」へ移動
「Generate new token」へ移動
「Note」に分かりやすいようにメモを入力
「Select scopes」は「repo」を選択
「Generate token」をクリック
アクセストークンが表示されるので、それをコピーしてなくさないように別ファイルで保存します。
次はSourcetreeでの作業です。
一部サイトでURLにトークンを入れる方法を書いているところもありますが、
それは危険なのでマネしないでください。
海外のフォーラムでも「それは危険」と指摘されているようです。
以下が解決方法です。
下記ディレクトリに移動します。
C:\Users\****\AppData\Local\Atlassian\SourceTree
passwdファイルを編集します。
アカウントと暗号化されたパスワードの2行があるので、その2行を削除します。
Sourcetreeを起動します。
再度プッシュします。
アカウントとパスワードを聞いてくるので、パスワードの欄にトークンを入力します。
これでプッシュができるようになります。
データをダウンロード処理したときにフラグを立てるなど色々処理をしている。
ダウンロード後にリダイレクトかリロードをしたいと思った。
ダウンロードの処理で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/"; };
AjaxZip3の処理を変更した話
大変便利なライブラリ
https://github.com/ajaxzip3/ajaxzip3.github.io
下記のようにinputのonKeyUpを使った場合
意図しない動きをすることがあった。
<input type="text" id="zip_code1" name="zip_code1" onKeyUp="AjaxZip3.zip2addr(this, 'zip_code2', 'address1', 'address1');" maxlength="3"> <input type="text" id="zip_code2" name="zip_code2" onKeyUp="AjaxZip3.zip2addr('zip_code1', this, 'address1', 'address1');" maxlength="4">
郵便番号を前半、後半の二つに分けている。
前半3桁。後半4桁です。
前半3桁、後半4桁入力すると住所欄に住所が入力される。
というのは正常な動き。
これを下記の条件にすると動きが変わる
「全角入力モードにした状態で前半3桁に7桁の郵便番号を入力するとonkeyupが作動し住所が入力される。」
入力確定前にonkeyupが動作しています。
inputはmaxlengthで3にしているので3桁しか入力されない。
onKeyUpはやめてjQueryで制御することにする。
$("#zip_code1,#zip_code2").on("keyup", function(){ if($("#zip_code1").val() != "" && $("#zip_code2").val() != ""){ AjaxZip3.zip2addr("zip_code1", "zip_code2",'address1','address1', '', '', false); } });
これで確定後の値で動作になるので意図した動きになりました。