PHP+SQLiteから始めるWebアプリケーションの作り方（その4）


## Webサーバ（HTTP）によるアクセス制御と認証

アクセス制御やHTTP上の認証の設定方法は、Webサーバによって異なります。なお、Document rootより浅い階層にアクセスされたくないファイルを置くことができるのならば、アクセスの防止はそのような形でも実現できます。

### Apache HTTP Serverによるアクセス制御
Apache HTTP Serverでは、主に.htaccessファイルを使ってアクセス制御を行います。Document root以下の対象のディレクトリに`.htaccess`ファイルを作成し、そこに決まった形式で設定を記述します。

```apache
Deny from All
```

これはそのディレクトリ以下へのすべての（HTTPによる）アクセスを拒否する（403を返す）という設定です（ただし、これを設置したディレクトリより深い階層に別の`.htaccess`ファイルを置くと上書きされることがあります）。

httpd.confファイルにアクセスできるのであれば、アクセス制御をそちらに記述することもできます。

mod_rewriteを使うとPHP側でルーティング（パスを読み取り、表示内容を変更する）ができます。

### nginx

nginx.confまたはこれにincludeされた設定ファイル（`/etc/nginx/sites-enabled/*`など）にアクセス制御設定を記述します。

```nginx
root /var/www/html;

location /data/ {
  deny all;
}
```

これは`/data/`以下（`/var/www/html/data`以下）へのアクセスを拒否する設定です。


### ベーシック認証
HTTPの認証機能にはベーシック認証とダイジェスト認証というものがありますが、ここではよりシンプルなベーシック認証のみを取り扱います（ダイジェスト認証はパスワードを通信路上でハッシュ化するという違い）。

認証情報はファイルとして管理できます。`apache2-utils`のプログラム`htpasswd`が便利なので、これを使います。Windowsの方はApache HTTP Serverのバイナリに同梱されています。

- Windowsの方：[Apache Lounge](https://www.apachelounge.com/download/)

```sh
htpasswd -c .htpasswd USERNAME
```

このコマンドで新しい`.htpasswd`ファイルが作成され、`USERNAME`ユーザとそのパスワードを登録できます（パスワードは対話形式で入力）。

Apache（`.htaccess`）では次のように設定します。

```apache
AuthType Basic
AuthName "Authentication Required"
AuthBasicProvider file
AuthUserFile HTPASSWD_PATH
Require valid-user
```

- [認証、承認、アクセス制御 - Apache HTTP サーバ バージョン 2.4](https://httpd.apache.org/docs/2.4/ja/howto/auth.html)

nginxでは次のように設定します。

```nginx
auth_basic "Authentication Required";
auth_basic_user_file HTPASSWD_PATH;
```

- [Module ngx_http_auth_basic_module - nginx](https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html)

このように、DBを書き換えるPHPスクリプトを認証下に置くことで簡易的な書き込み制限を設けることができます。ただし、この方法にはいくつかの問題点があります。

例えば、ベーシック認証はユーザ別認証をサポートしていますが、この方法でのアクセス制御には
サーバ管理者がユーザの追加削除の度にサーバサイドのファイルを半手動で編集する必要があります。
また、SSL化すれば暗号化されるとはいえ、対象のすべてのHTTPリクエストに平文で認証情報が乗ることになります。ほかにも、グループなどの複雑な制御は難しいなどの欠点があります。これらの問題のいくつかは、TLS化した上でCookieなどを利用したアカウント/セッションによる認証をアプリケーション側で用意することで、ある程度解決できます。

また、LAN内で提供されるサービスではしばしばHTTP通信の暗号化は行われないか、望ましくないとされるオレオレ証明書を使って暗号化することになってしまう場合がある（SSHポートフォワーディングなどを利用すれば別ですが）ことにも注意しておきましょう（積極的に安全な形で暗号化したいところなんですが..）。


## デプロイにあたって

デプロイ（アプリケーションのリリース）にあたって、いくつか必要になること、やっておいた方がいいことを書いておきます。

まず、サーバの用意が必要です。一般にサービスを公開したい場合は、レンタルサーバやVPSなどを借りるといいと思います。それほど規模が大きくなく、PHPならば安いレンタルサーバで事足りると思いますが、Webアプリケーションを公開できるプラットフォームとしてHerokuなどのサービスもあります。

特にVPSを借りる場合は、ドメインの取得と設定が必要です。条件によってはFreenomなど無料でドメインを取得できるサービスが利用できるほか、お名前.com、Google Domainsや、さくらインターネットなどのレンタルサーバ・VPSを取り扱っている会社がセットで扱っていたりします。だいたいTLDによって値段が異なり、また初年度の値段だけを強調するところもありますが、安いものなら年間1000円前後でしょうか。

現在はHTTP通信の通信路をTLSで暗号化するHTTPSに対応するのが一般的です。レンタルサーバなどでは管理画面での簡単な操作で設定が完結するほか、近年ではLet's Encryptという無料でTLS証明書を発行してくれるサービスがあります（以前は基本的に有料でした）。Let's Encryptは、簡単な対話形式のコマンド`certbot`を使って数回の入力で証明書を自動発行・Webサーバの設定を自動で書き換えてくれるほか、証明書の自動更新も管理してくれます。

アプリケーションのバージョン管理のため、Gitなどのバージョン管理システムとGitHubやGitLabなどのリモートリポジトリサービスを使うことをおすすめします。変更により動かなくなった部分の復元や過去のソースコードの再利用、活動時間の可視化などに利用できます。注意として、秘匿情報をパブリックなリポジトリに載せないようリポジトリの公開範囲や`.gitignore`を正しく設定しましょう。

アクセスされてはいけない場所に正しくアクセス制御が効いているか、データの処理方法・保存方法・表示方法に問題はないか、といったセキュリティチェックは重要です。また、本番環境と同じ環境を構築するのに[Docker](https://docs.docker.com/)が利用できます。

## さらなる改善
- MySQLへの移行（並行性の確保・パフォーマンスの改善）
   - [PDO](https://www.php.net/manual/ja/intro.pdo.php)の利用
- ファイルのアップロードと表示（特に画像）
  - [PHP: move_uploaded_file - Manual](https://www.php.net/manual/ja/function.move-uploaded-file.php)
- Markdownへの対応
  - [PHP Markdown Extra](https://michelf.ca/projects/php-markdown/extra/)
- アプリケーションでの認証
  - [PHP: password_hash - Manual](https://www.php.net/manual/ja/function.password-hash)
  - [PHP: password_verify - Manual](https://www.php.net/manual/ja/function.password-verify.php)
- フロントエンドライブラリの利用
   - [jQuery](https://jquery.com/)
   - [MathJax](https://www.mathjax.org/)（数式表示）
   - [Tagify](https://yaireo.github.io/tagify/)
- デザインの改善
  - [Bootstrap](https://getbootstrap.com/)

---

- [PHP+SQLiteから始めるWebアプリケーションの作り方（その1） - Qiita](https://qiita.com/aoirint/items/a95aa428bbb70f660d53)
- [PHP+SQLiteから始めるWebアプリケーションの作り方（その2） - Qiita](https://qiita.com/aoirint/items/3931c67fbfc494d1043d)
- [PHP+SQLiteから始めるWebアプリケーションの作り方（その3） - Qiita](https://qiita.com/aoirint/items/08e904e8e3b683325eab)
- [PHP+SQLiteから始めるWebアプリケーションの作り方（その4） - Qiita](https://qiita.com/aoirint/items/a0ebb62d8ea9a686e24d)