質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.75%

  • PHP

    19158questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • Apache

    1709questions

    Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

  • Laravel 5

    1691questions

    Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

  • .htaccess

    358questions

    Apacheウェブサーバーにおいて、ディレクトリ単位で設置及び設定を行う設定ファイルを指します。

【PHP】フォルダにアクセス制限をかけたい

解決済

回答 4

投稿

  • 評価
  • クリップ 2
  • VIEW 629

nnahito

score 1680

 やりたいこと

イメージ説明

上図の青色の枠の中ように、
HTML,CSS,JavaScript,画像等で構成された一つのWebページが一つのフォルダに入っております。

この、青色の枠の中は、会員登録を行ったユーザかつ、その中でも認証を行ったユーザのみしか閲覧されたくありません。

このアクセス制限の方法を考えているのですが、一向に手段が思い浮かばず、お知恵を貸していただきたいと存じます。

 行ったこと

ルーティング
Laravelのmod_rewrite処理を書いた.htaccessを青色の枠のフォルダ内におき、
access.phpのようなPHPファイルを別途作成し、そこにアクセスを転送させ、
SESSIONなどで認証を行っているかをaccess.phpで確認ができたらリダイレクトを行う。

まあ、もちろん無限ループになりました。


action
以下のような処理を書いた.htaccessを青色の枠のフォルダ内におき、
access.phpのようなPHPファイルを別途作成し、そこにアクセスを転送させ、
SESSIONなどで認証を行っているかをaccess.phpで確認ができたらリダイレクトを行う。
Action text/html /青枠のフォルダまでのパス/access.php

無限ループになりました。


後は、旧式の考えではありますが、フォルダにBASIC認証をかけようと思ったのですが、
ユーザには一度ログインを行ってもらっているので、再度BASIC認証で情報を入力してもらうのは良くなく、
そもそも、動的にユーザ情報を出力するのは難しそうなので躊躇しています。

PHP側で、BASIC認証用のヘッダを作成し、水色の枠の「メンバーページ」にログインしていたらBASIC認証を素通りでき、していなければこちらが用意した独自のログイン画面に遷移させ、
BASIC認証とは異なるログインをおこない、それがOKであればBASIC認証を行ったとすることは可能でしょうか?


ご存知の方がいらっしゃいましたら、やり方、ご意見等のお知恵を貸していただけますと幸いです。
よろしくお願いいたします。

 環境

PHP:7.2.3
Apache:2.4.6 (CentOS)

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • nnahito

    2018/04/15 13:28

    どうしても知りたいです

    キャンセル

  • nnahito

    2018/04/16 11:16

    そろそろ、luckerさんのご回答を見てみたいです

    キャンセル

回答 4

+2

Laravel使ってるのになんでこんな無駄なことを…。
Laravel使うなら素のPHPでのやり方の発想はほとんど捨てる。
隠したいファイルをpublicに置いてるのが間違い。
html置いてるのも意味が分からないけどそういえばここではそんな質問も多かった…。
根本的な発想がずれてるとどうにもならない。

ガチガチに制限したいなら全ファイルLaravelを通して表示させる。
/member/{file}のルーティングに対して
コントローラーからはファイルを返す。

return response()->file('secret/' . $file);


member/style.cssならsecret/style.css
secret/style.cssを直接表示はできずLaravelの認証を通ってないと不可なようにする。

現実的にはそこまでやる必要もなくページに対して制限すれば十分。
それならLaravelの普通の認証機能の範囲。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/15 15:56

    > Laravel使ってるのになんでこんな無駄なことを…。
    > Laravel使うなら素のPHPでのやり方の発想はほとんど捨てる。
    素の PHP でもこのやり方は考慮すると思うけど?
    そうでもないのかなぁ?

    キャンセル

  • 2018/04/15 15:59

    ご回答有り難うございます。

    Laravelで制限可能なのがよくわかりました。
    一応初心者マークもつけているので、そのあたり理解が及んでいない点については大目に見ていただき、合わせてご教示いただけますと幸いです。

    さて、今回の「return response()->file('secret/' . $file);」ですが、
    例えばHTMLの中の
    <script src="URL"></script>というタグについて、
    「return response()->file('secret/' . $file);」で返せるということでしょうか?

    キャンセル

  • 2018/04/15 16:33

    言ってることは suzukis さんの回答と同じですよ。
    コントローラに、パラメータ渡してやるだけなんで。
    <script src="URL">の URL はコントローラ+パラメータが入ります。
    パラメータ = ファイル指定の入力値確認が重要です。
    ホワイトリスト方式を取ったほうが良いです。

    キャンセル

  • 2018/04/15 16:41

    ご返信有難うございます。

    > <script src="URL">の URL はコントローラ+パラメータが入ります。
    なるほど、やはりそうなりますよね……

    今回、何故ワザワザデータを一つのフォルダとして、publicフォルダに配置したかと言うと、
    そのHTML,CSS,JSは、ディラのスクリプト( https://tyrano.jp/ )というゲームエンジンで吐き出されたものだからです。
    なので、エンジン内で作られたHTMLをすべて修正するのは困難であると判断し、このような手法を取っております。

    キャンセル

  • 2018/04/15 17:08 編集

    Laravel通すとオーバーヘッドかかるし静的ファイルはできるだけApacheに裁かせるほうが正解だと思う、これは素のPHPに関しても同じ(私見)

    そういう意味でasahinaさん支持

    キャンセル

  • 2018/04/15 17:21

    > mpyw さん
    私は、認証周りが分散するほうがイヤかなぁ。
    あとでわからんくなりそう。(同じく私見)

    > nnahito さん
    要件としては、「青色の枠」のファイル群(相対パスで各種リンクが記述された1サイト分のデータ)をリンクの変更なしに認証を通したセキュアなアクセスを提供したいってことですかね?
    多分、どっちのやり方(Apache or php)でもできそうですけど、もっと簡易なやり方がありそう。

    > kawax さん
    コメント欄で好き勝手言ってすみません^^;

    キャンセル

  • 2018/04/15 17:51

    本来PHPプロセスに対して,1リクエストで済むページがリソースのぶんだけリクエスト数増えるの,無視できないオーバーヘッドになると思うんですよね。時間空間的に分割されるならいいんですけど,連続で飛んでくるので特に深刻です。特にLaravel入れちゃう場合はブーティング処理が重たいのでスケーラビリティ最悪だと思います。

    キャンセル

  • 2018/04/15 18:15

    > te2jiさん
    >> 要件としては、「青色の枠」のファイル群(相対パスで各種リンクが記述された1サイト分のデータ)をリンクの変更なしに認証を通したセキュアなアクセスを提供したいってことですかね?

    そうですね、そのとおりのことを行いたいです。

    キャンセル

  • 2018/04/15 18:32

    > mpywさん
    >> 特にLaravel入れちゃう場合はブーティング処理が重たいのでスケーラビリティ最悪だと思います。

    なるほど、この点を考慮するとsuzukisさんのようなチェック方式のほうが確実ですが、Cookieを使ったほうがいい感じなんですね!

    キャンセル

  • 2018/04/17 00:57

    すいません、kawaxさんのやり方ですと、例えば青枠のデータ一式をviewsフォルダなどに入れて、外部からアクセスできないようにするのはわかりますが、

    > ガチガチに制限したいなら全ファイルLaravelを通して表示させる。
    > /member/{file}のルーティングに対して
    > コントローラーからはファイルを返す。

    この方法はどのように実現するのでしょうか?
    例えば、青枠フォルダの中のindex.htmlで呼ばれているCssやJSはどのようにアクセスが起こり、
    その際にはどのようにそのファイルが指定されているかを見極めるのでしょうか?

    キャンセル

+2

単純で汎用的な方法は、認証処理を含んだプログラム経由でコンテンツをサーブすることです。PHPならこんな感じで。

<?php
    $path = $_GET["path"];

    // $pathが不正なものでないかチェック

    // 認証および認可の処理

    header('Content-Type: ' + 適切な MIME type);
    readfile($path);
?>

http://example.jp/example.php?path=contents.html でアクセスします。

任意のパスが指定可能にならないよう、パラメータは必ずチェックしてください。


Webサーバが「認証済みかどうか」という「アプリケーション側の情報」を利用して動作を変えるのは基本難しいです。

アプリケーション側の「認証済み」という情報をアプリケーションを介さずに安全にWebサーバに伝えるのはとても困難です。単純に思いつくような方法(CookieにIDとか秘密の文字列のような何かの情報を載せるとか)は単純に突破可能なのでそんなことやるぐらいなら無条件で公開しても変わりません。

HTTP認証であればそれはWebサーバ側の情報になるので、それによって動作を変えることはある程度できます。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/15 16:37

    ご回答有り難うございます。

    この手法だと、htmlタグ内で呼び出しているCSSやJSは読み出せないような気がします。。。

    キャンセル

  • 2018/04/15 17:28

    <link rel="stylesheet" href="example.php?path=hoge.css">などとすればいいです。

    キャンセル

  • 2018/04/15 17:31

    ご返信有難うございます。

    やはりそうなりますよね……
    他コメントでも記載しましたが、
    今回、何故ワザワザデータを一つのフォルダとして、publicフォルダに配置したかと言うと、
    そのHTML,CSS,JSは、ディラのスクリプト( https://tyrano.jp/ )というゲームエンジンで吐き出されたものだからです。
    なので、エンジン内で作られたHTMLをすべて修正するのは困難であると判断し、このような手法を取っております。

    キャンセル

  • 2018/04/15 17:46

    /public/hoge.css→/example.php?path=hoge.cssというようなrewriteをHTTPサーバ側に仕込めばよいでしょう

    キャンセル

checkベストアンサー

+1

Basic 認証の情報が漏洩するぐらいなら

Apache のみで Cookie によるアクセス制御をかける

<VirtualHost *:80>
    ServerName www.sourcewalker.com
    DocumentRoot "/var/www/localhost/htdocs"
    SetEnvIf Cookie password=\x22?pass\x22? site_password
    <Location />
        Order deny,allow
        deny from all
        Allow from env=site_password
    </Location>
    <Files "/var/www/localhost/htdocs/auth.html">
        Order allow,deny
        Allow from all
    </Files>
</VirtualHost>

のようにすればいいと思います。

SetEnvIf にある Cookie password=\x22?pass\x22? は任意に変更してください

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/15 13:49

    あっこれ綺麗ですね!かなり良さげ

    キャンセル

  • 2018/04/15 14:01

    >あっこれ綺麗ですね!かなり良さげ

    うそーん…。

    キャンセル

  • 2018/04/15 14:05

    すごいどうでもいいけど

    <Location />
    </Location>

    ↑これの可読性の悪さ…w(Invalid な XML にしか見えない

    キャンセル

  • 2018/04/15 14:07

    ああ元サイトからコピーしてるからな・w・

    <Location "/">

    にしろよとおもったけどそこ直すとドメインもなおしたりしないと(いそいそ

    キャンセル

  • 2018/04/15 14:09 編集

    もっと言えば apache 2.2 か 2.4 か切り分けるあの認証モジュール判定もいれないとだし(apache のバージョンを明言していたな)

    キャンセル

  • 2018/04/15 14:12

    認証するのはPHPなのに判別するのはApacheなんだぁ…。

    キャンセル

  • 2018/04/15 14:12

    ご回答ありがとうございます!

    クッキーと言うことは、ブラウザで任意に付け加えたりできてしまい、
    アカウントを持っていない人でもページあるいは画像等が見えてしまいそうですが……
    その辺の解決策などはありますでしょうか?

    キャンセル

  • 2018/04/15 14:18

    Basic 認証埋め込み通信を見られたら終わりですが
    Cookie 認証だと何に利用してるものかぱっと見わかりませんので
    認証にこれをつかってるから勝手に埋め込まないでねとか書かない限り見られないかと

    キャンセル

  • 2018/04/15 14:29

    asahina先生は、ユーザーごとにみられるファイルが違う場合、ユーザーが増えるたびに.htaccess編集するの?

    キャンセル

  • 2018/04/15 14:41

    これは例 

    セクション:https://httpd.apache.org/docs/2.4/ja/sections.html
    認証:https://httpd.apache.org/docs/2.4/ja/mod/mod_authz_host.html#requiredirectives

    を組み合わせれば一度の記述でいけるよ

    キャンセル

  • 2018/04/15 14:44

    asahina先生、何いってんのかわかりません。

    キャンセル

  • 2018/04/15 15:13

    多分質問者はコントローラーでアクセス制御を行ったダウンロード以外の方法できいてるようなのだから
    ワイルドカード指定とかもそれほどひどいことにはならないと思うんだが

    キャンセル

  • 2018/04/15 15:14

    asahina先生、何いってんのかわかりません。ユーザーごとにみられるファイルが違う場合、どうなるんですかっ?

    キャンセル

  • 2018/04/15 15:50

    lucker あなたのお望みはこんなのですか?

    ※ mod_rewrite でうまく偽装する部分は省いてあります。

    キャンセル

  • 2018/04/15 15:50 編集

    <DirectoryMatch "/var/www/html/test/(.*)/css/(.*)">
    RewriteEngine ON
    RewriteCond %{HTTP_COOKIE} !UUID=%1
    RewriteRule - - [F]
    </DirectoryMatch>

    こっちになると SetEnvIf の手じゃないが

    キャンセル

0

静的な画像ファイル等へのリンクを出力する際

<img src="https://user:password@example.com/secret.jpg" alt="">

のようにすれば認証素通りできると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/15 13:41

    おおお!mpywさん!ご回答有難う御座います。
    ちょうど、 https://qiita.com/mpyw/items/bb8305ba196f5105be15 の記事などを拝見しておりました!

    https://user:password@example.com/secret.jpg
    上記URLはBASIC認証の回避ということでしょうか?

    また、これを実現するには、全部のURLに「user:password@」を指定していくしかない……という感じでしょうか?

    キャンセル

  • 2018/04/15 13:47

    >> 上記URLはBASIC認証の回避ということでしょうか?

    Basic認証はURLに直接認証情報を埋め込むことができるのでそれを利用しています。

    >> また、これを実現するには、全部のURLに「user:password@」を指定していくしかない……という感じでしょうか?

    `ob_start()` のコールバックで出力内容を正規表現等で書き換える,ということはできます。あるいはLaravelを使っているのであればミドルウェアを挟むのもありですね。

    キャンセル

  • 2018/04/15 14:09

    これ、getで送るのか… https://user:password@example.com/secret.jpg

    キャンセル

  • 2018/04/15 14:10

    ご返信ありがとうございます!


    > あるいはLaravelを使っているのであればミドルウェアを挟むのもあり

    こちらなのですが、今後、青枠のフォルダーが増えていくので、ページのHTMLもpublicフォルダに入れており、
    bladeでobjectタグを使って呼び出しています。

    この場合でも、ミドルウェアは利用できるのでしょうか?

    キャンセル

  • 2018/04/15 17:09 編集

    レンダリングされたHTMLを書き換えるだけなのでどんな場合でもできますよ(ただ手法としてはあんまりきれいじゃない)

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.75%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • PHP

    19158questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • Apache

    1709questions

    Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

  • Laravel 5

    1691questions

    Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

  • .htaccess

    358questions

    Apacheウェブサーバーにおいて、ディレクトリ単位で設置及び設定を行う設定ファイルを指します。