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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Apache

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

PHP

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

.htaccess

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

Laravel 5

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

Q&A

解決済

4回答

14444閲覧

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

nnahito

総合スコア2004

Apache

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

PHP

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

.htaccess

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

Laravel 5

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

1グッド

1クリップ

投稿2018/04/15 03:59

やりたいこと

イメージ説明

上図の青色の枠の中ように、
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)

mpyw👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nnahito

2018/04/15 04:28

どうしても知りたいです
nnahito

2018/04/16 02:16

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

回答4

0

単純で汎用的な方法は、認証処理を含んだプログラム経由でコンテンツをサーブすることです。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 06:48

編集2018/04/15 12:57
suzukis

総合スコア1449

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nnahito

2018/04/15 07:37

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

2018/04/15 08:28

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

2018/04/15 08:31

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

2018/04/15 08:46

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

0

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 06:29

kawax

総合スコア10377

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/04/15 06:56

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

2018/04/15 06:59

ご回答有り難うございます。 Laravelで制限可能なのがよくわかりました。 一応初心者マークもつけているので、そのあたり理解が及んでいない点については大目に見ていただき、合わせてご教示いただけますと幸いです。 さて、今回の「return response()->file('secret/' . $file);」ですが、 例えばHTMLの中の <script src="URL"></script>というタグについて、 「return response()->file('secret/' . $file);」で返せるということでしょうか?
退会済みユーザー

退会済みユーザー

2018/04/15 07:33

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

2018/04/15 07:41

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

2018/04/15 08:08 編集

Laravel通すとオーバーヘッドかかるし静的ファイルはできるだけApacheに裁かせるほうが正解だと思う、これは素のPHPに関しても同じ(私見) そういう意味でasahinaさん支持
退会済みユーザー

退会済みユーザー

2018/04/15 08:21

> mpyw さん 私は、認証周りが分散するほうがイヤかなぁ。 あとでわからんくなりそう。(同じく私見) > nnahito さん 要件としては、「青色の枠」のファイル群(相対パスで各種リンクが記述された1サイト分のデータ)をリンクの変更なしに認証を通したセキュアなアクセスを提供したいってことですかね? 多分、どっちのやり方(Apache or php)でもできそうですけど、もっと簡易なやり方がありそう。 > kawax さん コメント欄で好き勝手言ってすみません^^;
mpyw

2018/04/15 08:51

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

2018/04/15 09:15

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

2018/04/15 09:32

> mpywさん >> 特にLaravel入れちゃう場合はブーティング処理が重たいのでスケーラビリティ最悪だと思います。 なるほど、この点を考慮するとsuzukisさんのようなチェック方式のほうが確実ですが、Cookieを使ったほうがいい感じなんですね!
nnahito

2018/04/16 15:57

すいません、kawaxさんのやり方ですと、例えば青枠のデータ一式をviewsフォルダなどに入れて、外部からアクセスできないようにするのはわかりますが、 > ガチガチに制限したいなら全ファイルLaravelを通して表示させる。 > /member/{file}のルーティングに対して > コントローラーからはファイルを返す。 この方法はどのように実現するのでしょうか? 例えば、青枠フォルダの中のindex.htmlで呼ばれているCssやJSはどのようにアクセスが起こり、 その際にはどのようにそのファイルが指定されているかを見極めるのでしょうか?
guest

0

ベストアンサー

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 04:46

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mpyw

2018/04/15 04:49

あっこれ綺麗ですね!かなり良さげ
退会済みユーザー

退会済みユーザー

2018/04/15 05:01

>あっこれ綺麗ですね!かなり良さげ うそーん…。
mpyw

2018/04/15 05:05

すごいどうでもいいけど <Location /> </Location> ↑これの可読性の悪さ…w(Invalid な XML にしか見えない
退会済みユーザー

退会済みユーザー

2018/04/15 05:07

ああ元サイトからコピーしてるからな・w・ <Location "/"> にしろよとおもったけどそこ直すとドメインもなおしたりしないと(いそいそ
退会済みユーザー

退会済みユーザー

2018/04/15 05:14 編集

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

退会済みユーザー

2018/04/15 05:12

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

2018/04/15 05:12

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

退会済みユーザー

2018/04/15 05:18

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

退会済みユーザー

2018/04/15 05:29

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

退会済みユーザー

2018/04/15 05:44

asahina先生、何いってんのかわかりません。
退会済みユーザー

退会済みユーザー

2018/04/15 06:13

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

退会済みユーザー

2018/04/15 06:14

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

退会済みユーザー

2018/04/15 06:50

lucker あなたのお望みはこんなのですか? ※ mod_rewrite でうまく偽装する部分は省いてあります。
退会済みユーザー

退会済みユーザー

2018/04/15 06:51 編集

<DirectoryMatch "/var/www/html/test/(.*)/css/(.*)"> RewriteEngine ON RewriteCond %{HTTP_COOKIE} !UUID=%1 RewriteRule - - [F] </DirectoryMatch> こっちになると SetEnvIf の手じゃないが
guest

0

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

html

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

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

投稿2018/04/15 04:38

mpyw

総合スコア5223

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mpyw

2018/04/15 04:47

>> 上記URLはBASIC認証の回避ということでしょうか? Basic認証はURLに直接認証情報を埋め込むことができるのでそれを利用しています。 >> また、これを実現するには、全部のURLに「user:password@」を指定していくしかない……という感じでしょうか? `ob_start()` のコールバックで出力内容を正規表現等で書き換える,ということはできます。あるいはLaravelを使っているのであればミドルウェアを挟むのもありですね。
nnahito

2018/04/15 05:10

ご返信ありがとうございます! > あるいはLaravelを使っているのであればミドルウェアを挟むのもあり こちらなのですが、今後、青枠のフォルダーが増えていくので、ページのHTMLもpublicフォルダに入れており、 bladeでobjectタグを使って呼び出しています。 この場合でも、ミドルウェアは利用できるのでしょうか?
mpyw

2018/04/15 08:09 編集

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問