ゴマちゃんフロンティア

アザラシが大好きなエンジニアの開発日記です

【PHP】URLごとのBASIC認証を.htaccessのみで実現する方法

time 2017/05/16

というわけで、今回はWebシステムのお仕事で詰まってしまったことについてお話します。「PHP」と接頭辞が付いていますが、どちらかと言うとWebサーバ(Apache)寄りのお話かもしれません。

題名通り、WebサイトのBASIC認証に関する内容です。
「URLごとの認証なんて.htaccessで楽々~」かと思いきや、.htaccess上ではLocationディレクティブが使えないため、ちょっと詰まってしまいました。

何も書いていないのに結論から言うと、
「RewriteでルーティングのベースとなるPHPファイルを切り替え、Fileディレクティブで制御」で実現しています。

まえおき

よく通販サイトにあるような、一般公開側と管理側に分かれているシステムで、その管理側にのみBASIC認証を付けたいという要望がありました。
構築先はレンタルサーバで、Apacheは1.3、PHPは5.3とかなり古く、設定ファイルをいじることもできません。

今回フレームワークとして「Symfony2(+Silex)」を使用していたため、どのURLでアクセスしてもindex.phpにリダイレクトされ、フレームワーク側でURLが自動生成されます。メジャーなところではEC-CUBE3がこんな仕組みになっています。
Symfony2に限らず、フレームワーク (Laravelとか) ではルーティングの仕組みが使われていることが多いです。その場合、アクセス先は常にベースとなるPHPファイルになるため、どうしてもURLによる制御が必要になってきます。

そこで、ベースとなるPHPファイルを複数用意し、RewriteでURIを判断して切り替え、各々にFileディレクティブで設定という形で実現してみました。

前述しましたが、Locationディレクティブは「.htaccess」上では使えないようです。公式マニュアルのコア機能ページに書かれています。
https://httpd.apache.org/docs/2.4/ja/mod/core.html#location

実現方法

EC-CUBE3.0系の最新バージョン(3.0.14)を例に紹介します。
https://github.com/EC-CUBE/ec-cube/tree/3.0.14

ここでは「商品詳細画面」遷移時にBASIC認証を求めるようにしてみました。

ルーティングのベースとなるPHPファイルの複製

ベースとなっているhtml/index.phpを複製し、別名 (この例ではdetail.php) で保存しておきます。
中身は全く同じなので、ここでは割愛します。

.htaccessの編集

EC-CUBE3の場合、ベースファイルに飛ばすためのRewrite設定がhtml/.htaccessに書かれています。

EC-CUBE3の次期バージョンでは「html」フォルダがなくなるという話があります。まだテスト段階のようですが、今後3.0系以外をお使いの方はご注意ください。

19行目あたりにindex.phpへのRewriteが書いてあるので、これをコピペして修正し、既存のRewriteの上に追加します。

    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !^(.*)\.(gif|png|jpe?g|css|ico|js|svg)$ [NC]
    RewriteCond %{REQUEST_URI} ^.*/products/detail/.*$
    RewriteRule ^(.*)$ detail.php [QSA,L]

商品詳細のURL/product/detailに来た場合のみ、detail.phpにアクセスさせます。この状態でFilesディレクティブを設定し、detail.phpにのみBASIC認証が掛かるようにします。

<Files detail.php>
AuthUserfile E:\.htpasswd
AuthName "test"
AuthType Basic
require valid-user
</Files>

BASIC認証の設定は適当なので、実際に使用する場合はより詳しいサイトで確認することをおすすめします。
商品詳細画面にアクセスし、正常に動作するか確認しましょう。

あとがき

そんなわけで、ルーティング時のBASIC認証について.htaccessを使って区別させてみました。あまり見かけないケースかとは思いますが、忘れたときに悲惨なので、備忘として載せておきます。

down

コメントする