Closed yanachuwan9sm closed 6 months ago
RFC(Request For Comment)なのに、仕様書って何で?という疑問に早速答えてくれてる。
HTTPの仕様は後方互換性を維持するように作られていますが、セキュリティ関連のもの以外はなるべく新しい方を使う方が良いでしょう
セキュリティ関連のヘッダーイマイチ理解してないな〜〜
HTTPは、電子メールから ヘッダー + 本文 を、NNTP(Network News Transfer Protocol)からメソッドとステータスを導入したのか。そして、全ての始まりとしては電子メールから。
100番台 : 処理中の情報の伝達。そこそこ特殊なユースケース。
200番台 : 成功時のレスポンス。
300番台 : サーバーからクライアントへの命令。リダイレクトやキャッシュの利用を指示。(エラーではなく、あくまで正常処理の範疇)
400番台 : クライアントから送られたリクエストに不備がある場合に渡されるもの
500番台 : サーバー内部でエラーが発生した場合にクライアントに渡されるもの
ステータス | メソッド変更 | 永続的 or 一時的 | キャッシュ | 説明 |
---|---|---|---|---|
301 (Moved Premanently) | ◯ | 永続的 | する | ドメイン移転、ウェブサイト引っ越し、HTTPS化 |
302 (Found) | ◯ | 一時的 | 指示があれば | 一時メンテナンス、モバイルページ転送 |
303 (See other) | 許可 | 永続的 | しない | ログイン後のページ遷移 |
307 (Temporary Redirect) | 一時的 | 指示があれば | RFC7231で追加 | |
308 (Moved Redirect) | 永続的 | する | RFC7538で追加 |
301/308 -> リクエストされたページが別の場所へ移動した場合に使用する。(Googleは検索エンジン側にページ移動を伝える手段として、301を推奨)
302/307 -> 一時的な移動(モバイル専用サイトに移動、メンテナンスページの表示)
303 -> リクエストされたページには返すべきコンテンツが存在しない or 本来返すべきページが別にある場合に遷移させる。
ステータスコードが301、302、303で、GET以外のメソッドだった場合はGETメソッドでリダイレクトを送り直す。 👉 そのため、メソッド変更に許可が必要なステータスコード 307 308 が追加されている。
なぜNext.jsは307と308を使うのですか?従来、一時的なリダイレクトには302、恒久的なリダイレクトには301が使われていましたが、多くのブラウザは元のメソッドに関係なく、リダイレクトのリクエストメソッドをGETに変更しました。たとえば、ブラウザがPOST /v1/usersリクエストを行い、ステータスコード302と location/v2/users を返した場合、その後のリクエストは期待されたPOST /v2/users ではなくGET /v2/usersになるかもしれません。Next.jsは、307一時リダイレクトと308永久リダイレクトのステータスコードを使って、使用されたリクエストメソッドを明示的に保持します。
permanentをtrueにするとステータスコードは308となり、リダイレクトがキャッシュに保存されます。falseにするとステータスコードは307となり、リダイレクトはキャッシュされません。 https://nextjs.org/docs/pages/api-reference/next-config-js/redirects
URL構造におけるクエリーの部分で使用できる文字はパーセントコーディングっていうのか。
(ただのURLエンコードかと思ってた)
👉 JSなら encodeURIComponent()
とか URLSearchParams
で対応
URLを構成する文字列は ASCII。(RFC2718において、UTF-8を用いてパーセントコーディングすることで日本語も対応可能) -> 最近のブラウザはデコードした文字列が表示されることが多くなった。
漢字一文字 -> UTF-8で3バイド -> パーフェクトコーディングで9バイド(ぬおっ)
x-www-form-urlencoded
)ファイル送信に必要な情報全てを送ることは出来ない。(ファイル名のみが送信されてしまう)
<from method="POST">
<input name="title" />
<input name="author" />
<input name="submit />
</form>
curl --http1.0 --data-urlencode title="Head First PHP & MySQL" --data-urlencode author="Lynn Beightley, Michel Morrion" http://locahost:18888
// output
title=Head+First+PHP+%26+MySQL&author=Lynn+Beightley%2C+Michel+Morrion
multipart/form-data
)項目ごとに、追加のメタ情報をタグとして保持することができる。
@ファイル名
は x-www-form-urlencode でも使用できる。(その場合はファイル名ではなくファイルの内容が展開されて送信される)
curl --http1.0 -F title="Head First PHP & MySQL" -F author="Lynn Beightley, Michel Morrion". -F attachment-file=@test.txt http://localhost:18888
// output
POST / HTTP/1.0
Host: localhost:18888
Connection: close
Accept: */*
Content-Length: 444
Content-Type: multipart/form-data; boundary=------------------------85380971a6fac188
User-Agent: curl/7.77.0
--------------------------85380971a6fac188
Content-Disposition: form-data; name="title"
Head First PHP & MySQL
--------------------------85380971a6fac188
Content-Disposition: form-data; name="author"
Lynn Beightley, Michel Morrion.
--------------------------85380971a6fac188
Content-Disposition: form-data; name="attachment-file"; filename="test.txt"
Content-Type: text/plain
hello
--------------------------85380971a6fac188--
コンテントネゴシエーション!?始めて聞きました(白目)
https://zenn.dev/ritou/articles/b5cfeef911f9b3
(set-cookieを)送ったら次から(Cookieとして)送り返してくるヤツ。 👉 ブラウザは Set-Cookie してきたサイトを覚えておき、そのサイトにアクセスするたびに Cookie ヘッダで自動で送り返す。 👉 いわゆる画面に表示される URL だけではなく、そのサブリソース(image/JavaScript/iFlame)にも適用される。
一意な値を Cookie として付与すれば、ユーザが 区別 できるが、この時点では 識別 はしてない
最近の EC サービスは、ログインしていなくてもショッピングカートに追加でき、決済直前で認証を挟む実装が多いが、これは先にカートのための 区別 を行い、あとから 識別 していることになる。
Cookie とは必ずしも認証結果というわけではなく、ユーザ同士が 区別 できれば良いだけのユースケースもあるというのが、 Cookie の使い方を考える上で非常に大事なことだ。 3PCA 2 日目: Cookie による区別と識別 | blog.jxck.io
セッション 👉 サーバー側にデータを保存する仕組み。(サーバーがユーザーの情報や状態をセッションID(番号)として記憶しておくためのもの)
ヘッダの中に情報を入れて相手を識別する点では全く同じです。 それがCookieの場合は丸裸の情報になっていて、セッションの場合は受付番号になっているかの違い。
(HTTPはその時の要求に対しての応答を返すだけで、前回の状態を保持できないステートレスなプロトコルであるため)クライアントとサーバーの間のセッション状態を保持する方式として Cookie & Sessionを用いる必要がある。
そのセッション情報(セッションID)をどこ(セッションストレージ)に保存するかで大きく三種類ある。 👉 クッキーにする?Redisにする?サーバーのメモリにする?
● CookieStore(クッキー方式)
● Redis(インメモリ方式)
● DB(データベース方式)
以下はRedis(またはDB)の場合の処理の一連の流れ。
Set-Cookie
)。ユーザーのセッション情報をスケーラブルに保つ 2 つの方法 #JavaScript - Qiita
署名付きURL と 署名付きクッキー の違い あんまり理解してないかもしれない。
署名付きクッキー https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-cookies.html#private-content-how-signed-cookies-work https://zenn.dev/tera_ny/articles/034c2cca6674b3
3rd party cookieとは?については以下の記事がめちゃめちゃ分かりやすい。 https://blog.jxck.io/entries/2023-12-04/3pca-3rd-party-cookie.html
HTTP キャッシュの動作は、リクエスト ヘッダーとレスポンス ヘッダーの組み合わせで制御されます。ウェブ アプリケーションのコード(リクエスト ヘッダーを決定)とウェブサーバーの構成(レスポンス ヘッダーを決定)の両方を制御するのが理想的
デフォルト設定(ブラウザ)のままが一般的。
ほとんどの場合、ブラウザがリクエストを行う際に、ユーザーに代わってそれらのヘッダーを設定している。
更新頻度のチェックに影響するリクエスト ヘッダー(If-None-Match や If-Modified-Since など)は、HTTP キャッシュ内の現在の値に対するブラウザの認識に基づいて表示されます。
ウェブサーバーがレスポンスを送信する際に、明示的にヘッダーを追加し、細かく制御する必要がある。
(ちなみに、ブラウザは、そのコンテンツ タイプに最も適したキャッシュ動作のタイプを実質的に推測するため、Cache-Control レスポンス ヘッダーを省略しても HTTP キャッシュは無効にならない)
キャッシュを制御する主なヘッダーは以下の3通り。また、考慮するべき優先度は Cache Control > ETag > Last-Modified 。
サーバーは Cache-Control ディレクティブを返して、ブラウザやその他の中間キャッシュが個々のレスポンスをキャッシュに保存する方法と保存期間を指定できます。
Cache-Control: no-cache
👉 使用前にサーバーで再検証する必要があるリソースに使用。Cache-Control: no-store
👉 キャッシュに保存しないリソースに使用。Cache-Control: max-age=31536000
👉 バージョニングされたリソース用。Cache-Control 値 | 説明 |
---|---|
max-age=86400 | レスポンスは、最大 1 日間(60 秒 x 60 分 x 24 時間)ブラウザおよび中継キャッシュでキャッシュに保存できます。 |
private, max-age=600 | レスポンスはブラウザで最大 10 分(60 秒 x 10 分)キャッシュに保存できますが、中継キャッシュは保存できません。 |
public, max-age=31536000 | レスポンスは、任意のキャッシュに 1 年間保存できます。 |
no-store | レスポンスをキャッシュに保存することはできず、リクエストごとに完全に取得する必要があります。 |
RFC 5861 - 古いコンテンツ用のHTTPキャッシュコントロール拡張にて追加された stale-while-revalidate
を用いる事で、キャッシュが古くなった時一旦はそれをユーザーに見せながら裏で最新のデータを取得することで、サーバーへのリクエストにかかる時間をユーザーから隠蔽できるのが嬉しい。
しかし、主要ブラウザーにおいて、全て対応されている訳ではないことがマイナスポイント。
ETag と Last-Modified はどちらも同じ目的を果たし、期限切れのキャッシュ ファイルを再ダウンロードする必要があるかどうかをブラウザが判断する。(ETag は、精度が高いため推奨される方法)
ブラウザは、期限切れのキャッシュされたレスポンスを見つけると、小さなトークン(通常はファイルのコンテンツのハッシュ)をサーバーに送信して、ファイルが変更されたかどうかを確認できます。サーバーから同じトークンが返された場合は、ファイルは同じであるため、再度ダウンロードする必要はありません。
1999 年当時のキャッシュ保存のデフォルト設定。 このヘッダーの目的は ETag と同じですが、ETag のコンテンツ ベースの戦略ではなく時間ベースの戦略を使用して、リソースが変更されたかどうかを判断します。
HTTPキャッシュとは異なるものとしてBFキャッシュもある。
1、2章の内容を実際に curlコマンド(Go言語でGET/POSTメソッドを叩く)で確認するやつ。 curlでも動作確認はできるから、GO言語を学びたい(組み込みインターフェースの説明が主)以外の理由がなければ別にさらっ〜と読み飛ばしていいかも。
Golangでここら辺を実装する際は読み直すといいのかも、、、?
4章では以下の項目の中でもTLSの説明に多くのページを割かれている。(それほどHTTP/1.1におけるTLSのサポートのインパクトが大きかったと言うこと??)
Keep-Alive
がデフォルトで有効)概要だけは復習したけど、TLS 1.3 の TLSハンドシェイクのシーケンスやら鍵交換アルゴリズム周りには全く触れていないので、ガッツリ学ぶまで行かなくとも、HTTP/3 における TLS の立ち位置やらセキュリティの部分は普段からアンテナを立てておく必要があるな〜と思った。
OPTIONとCONNECTメソッドっていつ使うんですか、、、?
これが誕生するまでは、デフォルトのHTTPリクエストしか無かった。(裏技的なものはあった) これにより以下のメリットが生まれた。
ただし、便利な反面セキュリティの強化する観点から、Sama Origin Policy や CORS が生まれた。
XMLと何が関係あるん?ってずっと疑問に思ってたけど、 IEに無理やり組み込むために、XML処理ライブラリのリリースと被せるにあたって HTTP用途のものなのに、便宜上「XML」と言う名前がついたものがリリースされたのか。 歴史を知るとなかなか面白い由来。
そこまで深くない、これまでのRPCの歴史がさらっ〜と書いてある程度。 そんなにしっかりではなくゆるく読んだぐらい。 HTTP 1.1 が出来たぐらいに生まれたもので歴史があるんだな〜と言う温度感。 XML-RPC > SOAP > JSON-RPC
HTTPプロトコルを拡張した分散ファイルサービスの事らしい。(知らんかった)
この技術を活用して現在普及しているサービスで言うと、Googleドライブなどのオンラインストレージ・サービス(クラウド上で複数の利用者が、ファイル共有とその場での編集作業を比較的安全に行うことが可能)
HTTPは、自組織への不正侵入を防ぐためにプロトコルに応じて出入りを許可したり禁止したりすることでセキュリティレベルを維持する仕組み(ファイアウォール)を通過できるから、HTTPを拡張し、WebDAVでファイル共有という機能を実現しちゃおぜ!的なモチベなのかな???
HTTPプロトコルに機能が増えてリッチなアプリケーションになるにあたって、 アプリケーションとして出来ることが増えた = 認証・認可の重要性が高まってきたからこの章で紹介されてる感じ??とりあえず今現在でもマストで抑えている必要がある部分ではある。
↓ OpenID関連技術仕様の日本語訳や、プレゼンテーション資料、その他各種文書 https://openid.or.jp/document/
認証・認可プラットフォームに関しては、ざっくり読んで別途ちゃんとやる!!
↓OAuth、OpenID Connect についてはScrapboxでまとめた↓ https://scrapbox.io/trashbox97/OAuth https://scrapbox.io/trashbox97/OpenID_Connect
とりあえず後回し。(後でやる)
HTTP/2の大きな目的は「通信の高速化」。HTTP/1.1からの変更点は以下の通り。
・ストリームを使ってバイナリデータを多重に送受信する仕組みに変更 ・ストリーム内での優先順位や、サーバーサイドからデータ通信を行うサーバーサイドプッシュを実装 ・ヘッダー部が圧縮されるようになった。
理解が難しい所や今理解する必要がなさそうな所は「さら読み」 重要そうな部分は別途技術書で理解を深めるなどする。