HTTPとHTTPSの違い

## HTTPとは
・HTTP(Hyptertext Transfer Protocol)はWebサーバとWebブラウザの間でWeb情報をやり取りするためのプロトコル(通信規則)
・多くの場合、HTTPはTCPと組み合わせて使い、UDPと組み合わせるケースは稀。サーバがHTTP通信を受け取るポート番号は通常80番。HTTPプロキシ(高パフォーマンスのコンテンツフィルタなど)で特殊な用途で利用する場合は、80番ポート以外を利用する

## HTTPとHTTPSの違い
HTTPとHTTPSの違いは通信が暗号化されていないか暗号化されているかの違いで、HTTPSは暗号化されている。HTTPS(Hypertext Transfer Protocol Secure)は、HTTPで安全に通信を行うための仕組み。HTTPSのポート番号は443番が割り当てられている。
HTTPSは特別なプロトコルが定められているわけではなく、SSL(Secure Sockets Layer)/TLS(Transport Layer Security)と呼ばれる安全な接続を使って、その上でHTTPによる通信を行う。そのため、HTTPの持つシンプルで汎用性の高い特性はそのまま活かされている。
HTTPSは盗聴することができず、改ざんを検知することもできる。

## SSLサーバ証明書とHTTP暗号化通信
HTTPSによる暗号化通信はSSLサーバ証明書をサーバにインストールして実現できる
認証レベルにもDV認証、OV認証、EV認証と別れている

## httpsのページが表示されるまでの流れ
httpsではじまるURLにウェブブラウザがアクセスしようとすると、クライアント(ブラウザ)とサーバ間で以下のようなネゴシエーションが行われる
1. ブラウザはサーバにhttpsリクエストを送信
2. ブラウザとサーバで利用する暗号方式を決定
3. サーバからブラウザにSSLサーバ証明書と公開鍵を送付
4. ブラウザはプリマスターシークレットを送信し、ブラウザとサーバで共通鍵を生成
5. ブラウザとサーバは共通鍵を使用して、データを暗号化して送受信する

## 暗号アルゴリズムの決定メカニズム
大抵の場合、クライアントとサーバは複数の暗号アルゴリズムを使用できる。そのため、通信を開始する前に、使用するアルゴリズムを決定しなければならない
1. クライアントはサーバにSSL通信をリクエストする際に、サーバに利用可能な暗号アルゴリズムを送付する
2. サーバは使用するアルゴリズムを選択し決定する
3. サーバはSSLサーバ証明書と利用する暗号アルゴリズムをクライアントに送信
4. クライアントはサーバから受信した情報に基づいてデータを暗号化

## アルゴリズムの選択
2048ビット長の鍵が主流
SSL通信で使用されるアルゴリズムは公開されている。暗号データは暗号化と復号で使用される鍵で守られている。アルゴリズムが解っているため、鍵が重要。鍵長を長くすることで暗号は解読されにくくなる。

$ openssl ciphers -v ‘HIGH’
TLS_AES_256_GCM_SHA384 TLSv1.3 Kx=any Au=any Enc=AESGCM(256) Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any Au=any Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_AES_128_GCM_SHA256 TLSv1.3 Kx=any Au=any Enc=AESGCM(128) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
DHE-DSS-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=DSS Enc=AESGCM(256) Mac=AEAD
DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=ECDSA Enc=CHACHA20/POLY1305(256) Mac=AEAD
ECDHE-RSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=RSA Enc=CHACHA20/POLY1305(256) Mac=AEAD
DHE-RSA-CHACHA20-POLY1305 TLSv1.2 Kx=DH Au=RSA Enc=CHACHA20/POLY1305(256) Mac=AEAD
ECDHE-ECDSA-AES256-CCM8 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESCCM8(256) Mac=AEAD
ECDHE-ECDSA-AES256-CCM TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESCCM(256) Mac=AEAD
DHE-RSA-AES256-CCM8 TLSv1.2 Kx=DH Au=RSA Enc=AESCCM8(256) Mac=AEAD
DHE-RSA-AES256-CCM TLSv1.2 Kx=DH Au=RSA Enc=AESCCM(256) Mac=AEAD
ECDHE-ECDSA-ARIA256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=ARIAGCM(256) Mac=AEAD
ECDHE-ARIA256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=ARIAGCM(256) Mac=AEAD
DHE-DSS-ARIA256-GCM-SHA384 TLSv1.2 Kx=DH Au=DSS Enc=ARIAGCM(256) Mac=AEAD
DHE-RSA-ARIA256-GCM-SHA384 TLSv1.2 Kx=DH Au=RSA Enc=ARIAGCM(256) Mac=AEAD
ADH-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=None Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(128) Mac=AEAD
ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD
DHE-DSS-AES128-GCM-SHA256 TLSv1.2 Kx=DH Au=DSS Enc=AESGCM(128) Mac=AEAD
DHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(128) Mac=AEAD
ECDHE-ECDSA-AES128-CCM8 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESCCM8(128) Mac=AEAD
ECDHE-ECDSA-AES128-CCM TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESCCM(128) Mac=AEAD
DHE-RSA-AES128-CCM8 TLSv1.2 Kx=DH Au=RSA Enc=AESCCM8(128) Mac=AEAD
DHE-RSA-AES128-CCM TLSv1.2 Kx=DH Au=RSA Enc=AESCCM(128) Mac=AEAD
ECDHE-ECDSA-ARIA128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=ARIAGCM(128) Mac=AEAD
ECDHE-ARIA128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=ARIAGCM(128) Mac=AEAD
DHE-DSS-ARIA128-GCM-SHA256 TLSv1.2 Kx=DH Au=DSS Enc=ARIAGCM(128) Mac=AEAD
DHE-RSA-ARIA128-GCM-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=ARIAGCM(128) Mac=AEAD
ADH-AES128-GCM-SHA256 TLSv1.2 Kx=DH Au=None Enc=AESGCM(128) Mac=AEAD
ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA384
ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384
DHE-RSA-AES256-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(256) Mac=SHA256
DHE-DSS-AES256-SHA256 TLSv1.2 Kx=DH Au=DSS Enc=AES(256) Mac=SHA256
ECDHE-ECDSA-CAMELLIA256-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=Camellia(256) Mac=SHA384
ECDHE-RSA-CAMELLIA256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=Camellia(256) Mac=SHA384
DHE-RSA-CAMELLIA256-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=Camellia(256) Mac=SHA256
DHE-DSS-CAMELLIA256-SHA256 TLSv1.2 Kx=DH Au=DSS Enc=Camellia(256) Mac=SHA256
ADH-AES256-SHA256 TLSv1.2 Kx=DH Au=None Enc=AES(256) Mac=SHA256
ADH-CAMELLIA256-SHA256 TLSv1.2 Kx=DH Au=None Enc=Camellia(256) Mac=SHA256
ECDHE-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA256
ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA256
DHE-RSA-AES128-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(128) Mac=SHA256
DHE-DSS-AES128-SHA256 TLSv1.2 Kx=DH Au=DSS Enc=AES(128) Mac=SHA256
ECDHE-ECDSA-CAMELLIA128-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=Camellia(128) Mac=SHA256
ECDHE-RSA-CAMELLIA128-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=Camellia(128) Mac=SHA256
DHE-RSA-CAMELLIA128-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=Camellia(128) Mac=SHA256
DHE-DSS-CAMELLIA128-SHA256 TLSv1.2 Kx=DH Au=DSS Enc=Camellia(128) Mac=SHA256
ADH-AES128-SHA256 TLSv1.2 Kx=DH Au=None Enc=AES(128) Mac=SHA256
ADH-CAMELLIA128-SHA256 TLSv1.2 Kx=DH Au=None Enc=Camellia(128) Mac=SHA256
ECDHE-ECDSA-AES256-SHA TLSv1 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA1
ECDHE-RSA-AES256-SHA TLSv1 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA1
DHE-RSA-AES256-SHA SSLv3 Kx=DH Au=RSA Enc=AES(256) Mac=SHA1
DHE-DSS-AES256-SHA SSLv3 Kx=DH Au=DSS Enc=AES(256) Mac=SHA1
DHE-RSA-CAMELLIA256-SHA SSLv3 Kx=DH Au=RSA Enc=Camellia(256) Mac=SHA1
DHE-DSS-CAMELLIA256-SHA SSLv3 Kx=DH Au=DSS Enc=Camellia(256) Mac=SHA1
AECDH-AES256-SHA TLSv1 Kx=ECDH Au=None Enc=AES(256) Mac=SHA1
ADH-AES256-SHA SSLv3 Kx=DH Au=None Enc=AES(256) Mac=SHA1
ADH-CAMELLIA256-SHA SSLv3 Kx=DH Au=None Enc=Camellia(256) Mac=SHA1
ECDHE-ECDSA-AES128-SHA TLSv1 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA1
ECDHE-RSA-AES128-SHA TLSv1 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA1
DHE-RSA-AES128-SHA SSLv3 Kx=DH Au=RSA Enc=AES(128) Mac=SHA1
DHE-DSS-AES128-SHA SSLv3 Kx=DH Au=DSS Enc=AES(128) Mac=SHA1
DHE-RSA-CAMELLIA128-SHA SSLv3 Kx=DH Au=RSA Enc=Camellia(128) Mac=SHA1
DHE-DSS-CAMELLIA128-SHA SSLv3 Kx=DH Au=DSS Enc=Camellia(128) Mac=SHA1
AECDH-AES128-SHA TLSv1 Kx=ECDH Au=None Enc=AES(128) Mac=SHA1
ADH-AES128-SHA SSLv3 Kx=DH Au=None Enc=AES(128) Mac=SHA1
ADH-CAMELLIA128-SHA SSLv3 Kx=DH Au=None Enc=Camellia(128) Mac=SHA1
RSA-PSK-AES256-GCM-SHA384 TLSv1.2 Kx=RSAPSK Au=RSA Enc=AESGCM(256) Mac=AEAD
DHE-PSK-AES256-GCM-SHA384 TLSv1.2 Kx=DHEPSK Au=PSK Enc=AESGCM(256) Mac=AEAD
RSA-PSK-CHACHA20-POLY1305 TLSv1.2 Kx=RSAPSK Au=RSA Enc=CHACHA20/POLY1305(256) Mac=AEAD
DHE-PSK-CHACHA20-POLY1305 TLSv1.2 Kx=DHEPSK Au=PSK Enc=CHACHA20/POLY1305(256) Mac=AEAD
ECDHE-PSK-CHACHA20-POLY1305 TLSv1.2 Kx=ECDHEPSK Au=PSK Enc=CHACHA20/POLY1305(256) Mac=AEAD
DHE-PSK-AES256-CCM8 TLSv1.2 Kx=DHEPSK Au=PSK Enc=AESCCM8(256) Mac=AEAD
DHE-PSK-AES256-CCM TLSv1.2 Kx=DHEPSK Au=PSK Enc=AESCCM(256) Mac=AEAD
RSA-PSK-ARIA256-GCM-SHA384 TLSv1.2 Kx=RSAPSK Au=RSA Enc=ARIAGCM(256) Mac=AEAD
DHE-PSK-ARIA256-GCM-SHA384 TLSv1.2 Kx=DHEPSK Au=PSK Enc=ARIAGCM(256) Mac=AEAD
AES256-GCM-SHA384 TLSv1.2 Kx=RSA Au=RSA Enc=AESGCM(256) Mac=AEAD
AES256-CCM8 TLSv1.2 Kx=RSA Au=RSA Enc=AESCCM8(256) Mac=AEAD
AES256-CCM TLSv1.2 Kx=RSA Au=RSA Enc=AESCCM(256) Mac=AEAD
ARIA256-GCM-SHA384 TLSv1.2 Kx=RSA Au=RSA Enc=ARIAGCM(256) Mac=AEAD
PSK-AES256-GCM-SHA384 TLSv1.2 Kx=PSK Au=PSK Enc=AESGCM(256) Mac=AEAD
PSK-CHACHA20-POLY1305 TLSv1.2 Kx=PSK Au=PSK Enc=CHACHA20/POLY1305(256) Mac=AEAD
PSK-AES256-CCM8 TLSv1.2 Kx=PSK Au=PSK Enc=AESCCM8(256) Mac=AEAD
PSK-AES256-CCM TLSv1.2 Kx=PSK Au=PSK Enc=AESCCM(256) Mac=AEAD
PSK-ARIA256-GCM-SHA384 TLSv1.2 Kx=PSK Au=PSK Enc=ARIAGCM(256) Mac=AEAD
RSA-PSK-AES128-GCM-SHA256 TLSv1.2 Kx=RSAPSK Au=RSA Enc=AESGCM(128) Mac=AEAD
DHE-PSK-AES128-GCM-SHA256 TLSv1.2 Kx=DHEPSK Au=PSK Enc=AESGCM(128) Mac=AEAD
DHE-PSK-AES128-CCM8 TLSv1.2 Kx=DHEPSK Au=PSK Enc=AESCCM8(128) Mac=AEAD
DHE-PSK-AES128-CCM TLSv1.2 Kx=DHEPSK Au=PSK Enc=AESCCM(128) Mac=AEAD
RSA-PSK-ARIA128-GCM-SHA256 TLSv1.2 Kx=RSAPSK Au=RSA Enc=ARIAGCM(128) Mac=AEAD
DHE-PSK-ARIA128-GCM-SHA256 TLSv1.2 Kx=DHEPSK Au=PSK Enc=ARIAGCM(128) Mac=AEAD
AES128-GCM-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AESGCM(128) Mac=AEAD
AES128-CCM8 TLSv1.2 Kx=RSA Au=RSA Enc=AESCCM8(128) Mac=AEAD
AES128-CCM TLSv1.2 Kx=RSA Au=RSA Enc=AESCCM(128) Mac=AEAD
ARIA128-GCM-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=ARIAGCM(128) Mac=AEAD
PSK-AES128-GCM-SHA256 TLSv1.2 Kx=PSK Au=PSK Enc=AESGCM(128) Mac=AEAD
PSK-AES128-CCM8 TLSv1.2 Kx=PSK Au=PSK Enc=AESCCM8(128) Mac=AEAD
PSK-AES128-CCM TLSv1.2 Kx=PSK Au=PSK Enc=AESCCM(128) Mac=AEAD
PSK-ARIA128-GCM-SHA256 TLSv1.2 Kx=PSK Au=PSK Enc=ARIAGCM(128) Mac=AEAD
AES256-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AES(256) Mac=SHA256
CAMELLIA256-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=Camellia(256) Mac=SHA256
AES128-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA256
CAMELLIA128-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=Camellia(128) Mac=SHA256
ECDHE-PSK-AES256-CBC-SHA384 TLSv1 Kx=ECDHEPSK Au=PSK Enc=AES(256) Mac=SHA384
ECDHE-PSK-AES256-CBC-SHA TLSv1 Kx=ECDHEPSK Au=PSK Enc=AES(256) Mac=SHA1
SRP-DSS-AES-256-CBC-SHA SSLv3 Kx=SRP Au=DSS Enc=AES(256) Mac=SHA1
SRP-RSA-AES-256-CBC-SHA SSLv3 Kx=SRP Au=RSA Enc=AES(256) Mac=SHA1
SRP-AES-256-CBC-SHA SSLv3 Kx=SRP Au=SRP Enc=AES(256) Mac=SHA1
RSA-PSK-AES256-CBC-SHA384 TLSv1 Kx=RSAPSK Au=RSA Enc=AES(256) Mac=SHA384
DHE-PSK-AES256-CBC-SHA384 TLSv1 Kx=DHEPSK Au=PSK Enc=AES(256) Mac=SHA384
RSA-PSK-AES256-CBC-SHA SSLv3 Kx=RSAPSK Au=RSA Enc=AES(256) Mac=SHA1
DHE-PSK-AES256-CBC-SHA SSLv3 Kx=DHEPSK Au=PSK Enc=AES(256) Mac=SHA1
ECDHE-PSK-CAMELLIA256-SHA384 TLSv1 Kx=ECDHEPSK Au=PSK Enc=Camellia(256) Mac=SHA384
RSA-PSK-CAMELLIA256-SHA384 TLSv1 Kx=RSAPSK Au=RSA Enc=Camellia(256) Mac=SHA384
DHE-PSK-CAMELLIA256-SHA384 TLSv1 Kx=DHEPSK Au=PSK Enc=Camellia(256) Mac=SHA384
AES256-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(256) Mac=SHA1
CAMELLIA256-SHA SSLv3 Kx=RSA Au=RSA Enc=Camellia(256) Mac=SHA1
PSK-AES256-CBC-SHA384 TLSv1 Kx=PSK Au=PSK Enc=AES(256) Mac=SHA384
PSK-AES256-CBC-SHA SSLv3 Kx=PSK Au=PSK Enc=AES(256) Mac=SHA1
PSK-CAMELLIA256-SHA384 TLSv1 Kx=PSK Au=PSK Enc=Camellia(256) Mac=SHA384
ECDHE-PSK-AES128-CBC-SHA256 TLSv1 Kx=ECDHEPSK Au=PSK Enc=AES(128) Mac=SHA256
ECDHE-PSK-AES128-CBC-SHA TLSv1 Kx=ECDHEPSK Au=PSK Enc=AES(128) Mac=SHA1
SRP-DSS-AES-128-CBC-SHA SSLv3 Kx=SRP Au=DSS Enc=AES(128) Mac=SHA1
SRP-RSA-AES-128-CBC-SHA SSLv3 Kx=SRP Au=RSA Enc=AES(128) Mac=SHA1
SRP-AES-128-CBC-SHA SSLv3 Kx=SRP Au=SRP Enc=AES(128) Mac=SHA1
RSA-PSK-AES128-CBC-SHA256 TLSv1 Kx=RSAPSK Au=RSA Enc=AES(128) Mac=SHA256
DHE-PSK-AES128-CBC-SHA256 TLSv1 Kx=DHEPSK Au=PSK Enc=AES(128) Mac=SHA256
RSA-PSK-AES128-CBC-SHA SSLv3 Kx=RSAPSK Au=RSA Enc=AES(128) Mac=SHA1
DHE-PSK-AES128-CBC-SHA SSLv3 Kx=DHEPSK Au=PSK Enc=AES(128) Mac=SHA1
ECDHE-PSK-CAMELLIA128-SHA256 TLSv1 Kx=ECDHEPSK Au=PSK Enc=Camellia(128) Mac=SHA256
RSA-PSK-CAMELLIA128-SHA256 TLSv1 Kx=RSAPSK Au=RSA Enc=Camellia(128) Mac=SHA256
DHE-PSK-CAMELLIA128-SHA256 TLSv1 Kx=DHEPSK Au=PSK Enc=Camellia(128) Mac=SHA256
AES128-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1
CAMELLIA128-SHA SSLv3 Kx=RSA Au=RSA Enc=Camellia(128) Mac=SHA1
PSK-AES128-CBC-SHA256 TLSv1 Kx=PSK Au=PSK Enc=AES(128) Mac=SHA256
PSK-AES128-CBC-SHA SSLv3 Kx=PSK Au=PSK Enc=AES(128) Mac=SHA1
PSK-CAMELLIA128-SHA256 TLSv1 Kx=PSK Au=PSK Enc=Camellia(128) Mac=SHA256

HTTP_PROXY, HTTPS_PROXY, FTP_PROXYとは

HTTPプロキシは高性能なコンテンツフィルタ
Webトラフィックを検査して、ウィルス、その他の種類の侵入可能性があるコンテンツを識別する

環境変数のHTTPS_PROXYは、サーバにHTTPS接続したい時に使用するproxyの設定

HTTP_PROXYは接続先がhttp://target…
HTTPS_PROXYは接続先がhttps://target…

proxy設定はOS側からネットにアクセスする際に経由するって意味合いね

AWS ALB常時SSL(HTTPS)のLaravel 6.x Middleware書き方

つらつらと書いていますが、仕様としては、middlewareを作成後、「### 5.Middleware(ForceHttpProtocol.php)にformatSchemeをoverrideする」に飛んで頂いて構いません。

# 背景
ACMで証明書を取得後、ALBでattachし、挙動テストすると、「完全には保護されていません」と表示される
->PRDのソースを確認すると、プロトコルがhttpで出力されている

<link rel="stylesheet" href="http://${domain}/css/main.css">

ソースコードではasset()で記載

<link rel="stylesheet" href="{{ asset('css/main.css') }}">

原因は、assetが、httpsではなく、httpを読みにいっているから。

# 要件
- 商用環境でhttp通信のリクエストの場合は、https通信にリダイレクト
- ただし、ローカル環境はhttp通信
- 商用環境リンクをフォームを含めて全てhttpsに変更

## 前準備
middlewareの追加
$ php artisan make:middleware ForceHttpProtocol

app/Http/kernel.php

protected $middleware = [
        //省略
        \App\Http\Middleware\ForceHttpProtocol::class,
    ];

### 1. secure()に書き換えるやり方
app/Http/Middleware/ForceHttpProtocol.php

public function handle($request, Closure $next)
    {
        if(!$request->secure() && env('APP_ENV') === 'production'){
            return redirect()->secure($request->getRequestUri());
        }
        return $next($request);
    }

上記では永久リダイレクトとなり、タイムアウトになる。

### 2. ‘https://’.$_SERVER[‘HTTP_HOST’].$_SERVER[‘REQUEST_URI’]にリダイレクト

public function handle($request, Closure $next)
    {
        if(!$this->is_ssl() && config('app.env') === 'production'){
            return redirect('https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
        }
        return $next($request);
    }

    public function is_ssl()
    {
        if ( isset($_SERVER['HTTPS']) === true )
        {
            return ( $_SERVER['HTTPS'] === 'on' or $_SERVER['HTTPS'] === '1' );
        }
        elseif ( isset($_SERVER['SSL']) === true )
        {
            return ( $_SERVER['SSL'] === 'on' );
        }
        elseif ( isset($_SERVER['HTTP_X_FORWARDED_PROTO']) === true )
        {
            return ( strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https' );
        }
        elseif ( isset($_SERVER['HTTP_X_FORWARDED_PORT']) === true )
        {
            return ( $_SERVER['HTTP_X_FORWARDED_PORT'] === '443' );
        }
        elseif ( isset($_SERVER['SERVER_PORT']) === true )
        {
            return ( $_SERVER['SERVER_PORT'] === '443' );
        }

        return false;
    }

これでhttpリクエストの場合も、httpsにリダイレクトされるようになる。
ただし、asset、routeなどのリンクが、httpsではなく、httpを読みにいく事象は解消されないまま

->urlのhelperを確認
Illuminate/Foundation/helper.php

function url($path = null, $parameters = [], $secure = null)

URLやViewのasset, redirectを全て書き換える?
嘘だろ?

### 3. パスをassetからurlに書き換える
AppServiceProvicerで商用ならtrue, 商用以外ならfalseのメソッドを作成

app/Providers/AppServiceProvider.php

use View;
public function boot()
    {
       $is_production = env('APP_ENV') === 'production' ? true: false;
       View::share('is_production', $is_production);
    }

続いて、viewで、assetをurlに変更して、上記の変数を第3パラメータに追加
resources/view/auth/login.blad.php

<form method="POST" action="{{ url('login', null, $is_production) }}">

一箇所修正して挙動確認。
URLがhttpsに変わっていることを確認
3~4ページぐらい修正を繰り返していると、早くも絶望的な気分になってくる

### 4. Laravelコレクティブ&Controllerでのhttpsパラメータの渡し方を確認
laravel collective

{!! Form::open(['method'=>'POST', 'action'=>['HogeController@confirm',null,$is_production] ]) !!}

controller

protected $is_production;

    public function __construct(){
        $this->is_production = env('APP_ENV') === 'production' ? true: false;
    }

// 戻るボタン処理
        if($action == '戻る'){
            return redirect()->action('HogeController@create', 302, null, $this->is_production)->withInput($inputs);
        }

うまくいかない。

縷々調査すると、ssetやrouteのプロトコルはformatSchemeで生成しているとのこと。
Illuminate/Routing/UrlGenerator.php

public function formatScheme($secure = null)
    {
        if (! is_null($secure)) {
            return $secure ? 'https://' : 'http://';
        }

        if (is_null($this->cachedScheme)) {
            $this->cachedScheme = $this->forceScheme ?: $this->request->getScheme().'://';
        }

        return $this->cachedScheme;
    }

### 5.Middleware(ForceHttpProtocol.php)にformatSchemeをoverrideする

use URL;
public function handle($request, Closure $next)
    {
        if(!$this->is_ssl() && config('app.env') === 'production'){
            return redirect('https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
        }
        if (env('APP_ENV') === 'production')
        {
            URL::forceScheme('https');
        }

        return $next($request);
    }

    public function is_ssl()
    {
        if ( isset($_SERVER['HTTPS']) === true )
        {
            return ( $_SERVER['HTTPS'] === 'on' or $_SERVER['HTTPS'] === '1' );
        }
        elseif ( isset($_SERVER['SSL']) === true )
        {
            return ( $_SERVER['SSL'] === 'on' );
        }
        elseif ( isset($_SERVER['HTTP_X_FORWARDED_PROTO']) === true )
        {
            return ( strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https' );
        }
        elseif ( isset($_SERVER['HTTP_X_FORWARDED_PORT']) === true )
        {
            return ( $_SERVER['HTTP_X_FORWARDED_PORT'] === '443' );
        }
        elseif ( isset($_SERVER['SERVER_PORT']) === true )
        {
            return ( $_SERVER['SERVER_PORT'] === '443' );
        }

        return false;
    }

このように書くことで、要件を満たすことができる
- 商用環境でhttp通信のリクエストの場合は、https通信にリダイレクト
- ただし、ローカル環境はhttp通信
- 商用環境リンクをフォームを含めて全てhttpsに変更

axiosとは?

– axiosは、HTTP通信を簡単に行うことができるJavascriptライブラリ
https://github.com/axios/axios
– 主にJsonの取得に利用される

### Features
– Make XMLHttpRequests from the browser
– Make http requests from node.js
– Supports the Promise API
– Intercept request and response
– Transform request and response data
– Cancel requests
– Automatic transforms for JSON data
– Client side support for protecting against XSRF

## サンプル
### npm install
$ npm install axios –save

### index.js
– axios.get(‘${url}’), axios.post(‘${url}’)と実装する
– get, post以外にも、request, delete, head, options, put, patch, getUriなどがある

var express = require('express');
var router = express.Router();

// axiosのインスタンス生成
const axiosBase = require('axios');
const axios = axiosBase.create({
	baseURL = '192.168.33.10:8000',
	headers: {
		'Content-Type' : 'application/json',
		'X-Requested-With': 'XMLHttpRequest'
	},
	responseType: 'json'
});

router.get('/', function(req, res, next){
	axios.get('/title')
	.then(function(response){
		res.render('index', response.data);
	})

	.catch(function(error){
		console.log('Error!! occurred in Backend.')
	});
});

module.exports = router;

### res, err, finally

<script>
		axios.get(${url})
		.then(res => console.log(res.data))
		.catch(err => console.error(err))
		.finally(res => console.log('finally'))
	</script>

XMLHttpRequestを生成せずに処理できるので、確かに使い勝手良さそうです。

ProxyPass、ProxyPassReverseを設定し、商用環境でexpressサーバに接続

## virtualhostで、ProxyPass、ProxyPassReverseを設定し、node appとすると、商用のドメインからでもexpressさーばに接続できるようになる。

vi /etc/httpd/conf.d/hoge.conf

<VirtualHost *:80>
DocumentRoot /var/www/html/hoge/express
ServerName www.target.com
ServerAlias target.com
CustomLog logs/target.com-access.log common
ErrorLog  logs/target.com-error.log
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
AddDefaultCharset UTF-8
<Directory "/var/www/html/hoge/express/">
AllowOverride All
</Directory>
</VirtualHost>

ProxyPassは転送
ProxyPassReverseはリダイレクト情報の書き換え

なるほど、expressサーバについて大分理解が深まった。expressサーバはapacheとは別ですね。
しかし、expressを使うところだけ、Jsonで取得するように、ユーザからのアクセスはProxyPassを使って転送させるって、アーキテクチャとしてどうなんだろうか。。。express単体のアプリケーションならいいが、フレームワークの中でexpressを使うってのは、仕組み的には可能だが、他の方法を探した方が建設的か。。。

Vagrant環境(amazon linux2)で、Expressを使ってhttpsサーバーを立てる

まず、sslモジュールをinstall
$ sudo yum install mod_ssl

続いてkeyとcertを作成して読み込む
# 手順
## certificate file作成
openssl req -newkey rsa:2048 -new -nodes -keyout key.pem -out csr.pem
openssl x509 -req -days 365 -in csr.pem -signkey key.pem -out server.crt

## package.json

{
	"name": "test-webrtc",
	"version": "0.0.1",
	"private": true,
	"dependencies": {
		"express": "4.x",
		"ejs": "3.0.1"
	}
}

$ npm install

## server.js

var express = require('express');
var app = express();

var fs = require("fs");
var https = require("https");
var options = {
	key: fs.readFileSync('key.pem'),
	cert: fs.readFileSync('server.crt')
}
var server = https.createServer(options, app);

console.log('server started');

app.get('/', function(req, res){
	res.render('index.ejs');
});

server.listen(3000);

$ node server.js

# 駄目な方法
## certificate file作成
$ openssl genrsa > server.key
$ openssl req -new -key server.key > server.csr
$ openssl x509 -req -signkey server.key < server.csr > server.crt

var express = require('express');
var app = express();

var fs = require("fs");
var https = require("https");
var options = {
	key: fs.readFileSync('server.key'),
	cert: fs.readFileSync('server.crt')
}
var server = https.createServer(options, app);

console.log('server started');

app.get('/', function(req, res){
	res.writeHead(200);
	res.render('index.ejs');
});

server.listen(3000);

## server.js
keyがpemファイルでないので、エラーが出ます
$ node server.js
_tls_common.js:88
c.context.setCert(options.cert);
^

Error: error:0906D06C:PEM routines:PEM_read_bio:no start line
at Object.createSecureContext (_tls_common.js:88:17)
at Server (_tls_wrap.js:819:25)
at new Server (https.js:60:14)
at Object.createServer (https.js:82:10)
at Object. (/home/vagrant/webrtc/server.js:10:20)
at Module._compile (module.js:653:30)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)

vagrantでhttpsの環境を作ろうとした時、opensslとphpのビルトインサーバーでhttps環境を作っていましたが、フロントエンドだけならexpressで十分だということがわかりました。
expressはhttpのみかと勘違いしていたが、よくよく考えたら、できないわけない😂😂😂

php build-in serverでhttpsサーバーを起動

ローカル環境で、httpsの挙動を確認したい時に使えるのが、hyper-builtinというライブラリ
https://github.com/mpyw/php-hyper-builtin-server

opensslでサーバー証明書を生成し、composerでhyper-builtinを入れて起動
※下はawslinuxだが、centosでも同様

### sslモジュールインストール(centOSの場合はmod_ssl)
$ sudo yum install mod24_ssl
$ httpd -M | grep ssl

### 秘密鍵作成
$ openssl genrsa > server.key

### CSR作成
$ openssl req -new -key server.key > server.csr

### サーバー証明書作成
$ openssl x509 -req -signkey server.key < server.csr > server.crt
$ rm server.csr

### 秘密鍵&サーバー証明書配置
$ sudo mkdir /etc/httpd/conf/ssl.key
$ sudo mkdir /etc/httpd/conf/ssl.crt
$ sudo mv server.key /etc/httpd/conf/ssl.key/
$ sudo mv server.crt /etc/httpd/conf/ssl.crt/

### ssl.conf編集
sudo vi /etc/httpd/conf.d/ssl.conf

# SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateFile /etc/httpd/conf/ssl.crt/server.crt
# SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLCertificateKeyFile /etc/httpd/conf/ssl.key/server.key

### apache再起動
$ sudo service httpd restart

### composerでhttps用のphp buildin-server libraryインストール
$ curl -sS https://getcomposer.org/installer | php
$ php composer.phar require –dev mpyw/php-hyper-builtin-server:^2.0

### httpsサーバー起動
$ vendor/bin/hyper-run -s 192.168.33.10:8000

うおおおおおおおおおおおおおお、めんどくせええええええええええええ
これ、playbook.ymlで一括管理してーーーーーーーーーーーーー

User Agent perspective

How to investigate user agent?
As an example, the user agent for IE9 is described as follows.

Mozilla / 5.0 (compatible;MSIE 9.0; Windows NT 6.1; Trident/5.0)

Application name
It corresponds to the “Mozilla” part. It is used in the sense that it has the function of the type of browser or its application.

Application Version
In the “5.0” part after Mozilla, it indicates the version of the application.

Platform token
It corresponds to the “Windows NT 6.1” part. It will be the display about OS.

Version Token
It corresponds to the part of “MISE 9.0”.Displaying browser version.

Compatibility Flags
It corresponds to the “Compatible” part. It shows the compatibility with Internet Explore.

Rendering engine
It corresponds to the part of “Trident/5.0”. Shows software that causes the browser to display the requested content.

Internet Explore
ver.11

Mozilla / 5.0 (Windows NT 6.3; ARM; Trident / 7.0; Touch; MALNJS; rv: 11.0) like Gecko

ver.10

Mozilla / 5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW 64; Trident / 6.0)

Chrome

Mozilla / 5.0 (Windows NT 5.1) AppleWebKit / 535.11 (KHTML, like Gecko) Chrome / 17.0.963.79 Safari / 535.11

Firefox

Mozilla / 5.0 (Windows NT 6.1; rv: 11.0) Gecko / 20100101 Firefox / 11.0

Safari

Mozilla / 5.0 (Macintosh; U; Intel Mac OS X; en-jp) AppleWebKit / 523.12 (KHTML, like Gecko) Version / 3.0.4 Safari / 523.12

Android

Mozilla / 5.0 (Linux; Android 4.4.2; 302KC Build / 101.0.2c00) AppleWebKit / 537.36 (KHTML, like Gecko) Version / 4.0 Chrome / 30.0.0.0 Mobile Safari / 537.36 YJApp-ANDROID jp.co.yahoo.android. ybrowser / 1.7.5

なるほど、内容よく見ると、どのブラウザか一発でわかりますね。まあ、一般的にユーザーエージェントは偽装されるのであまり意味ないかもしれませんが。そういえば、IPって偽装できるんでしょうか??? Chrome Extensionで、Hotspot Shieldを使えば偽装できるようですが。。

HTTP Trace method

In HTTP1.1 (RFC2616), eight kinds of methods are defined. GET, POST, HEAD, etc. are familiar, but there are five other types PUT, DELETE, OPTIONS, TRACE and CONNECT.
Of these, the TRACE method returns an HTTP request as “HTTP Parallel” as an HTTP response, and requests the Web server as TRACE instead of GET etc. as follows.

Apache setting file
/etc/httpd/conf/httpd.conf

あれ?TraceEnableないぞ。。

403 404 500 503

There are HTTP status codes from 100 series to 500 series. The 400th to 500th are the codes returned when there is an error with respect to the server or request.

403

403 is the code returned when access restriction etc is set.

It is displayed when IP restriction is applied and access is made from an IP address that is not permitted.
It is considered when there is access from other on the page to be displayed only in the company environment.

404

The code returned if the page does not exist. It is often displayed when deleting a page.

500
500 is a code returned in the case of CGI setting or program mistake. In case of this error, setting is wrong often, so it is necessary to modify permissions and code.

503
503 is the code returned when the number of accesses to the server has been exceeded and the server is under load. It is displayed when a large amount of access to the server gather at the same time.
In the case of a site where there are many instantaneous accesses, it is necessary to consider a server corresponding to that. Also, there is a possibility that may be attacked by a site.

Other representative HTTP status code
200 series
The 200 series means that the request to the server was successful. If you have successfully accessed the WEB, the status code “200” will be returned.

300 series
The 300 series is the code returned when doing redirect processing. Representative items such as “301” and “302” are listed.