HTTPはステートレス？？セッションとは？？Cookieとは？

##はじめに
初学者の個人的なまとめ記事に近く、だいぶ読みづらい点があると思いますがご了承ください。

##WebサーバーとWebクライアント
Webページはハイパーテキスト（HTML）というハイパーリンクというコンピューターに理解できる形式で記述されているので、瞬時に参照先の文章を閲覧できます。このハイパーテキストの公開と閲覧は**Webサーバー**と**Webクライアント**によって実現されています。
つまりWebサーバーはハイパーテキストを蓄積し、Webクライアントの要求に基づいて必要なファイルを渡します。

##URL
先程のWebクライアントがWebサーバーに目的のファイルを要求するためにファイルの場所がどこにあるのかを指定するのが**URL(Uniform Resource Locator)**です。
URLは以下のように構成されます。

###スキーム
スキームつまり通信手段はリソースを取得するための方法を表します

| スキーム名 | 説明 |
|:---:|:---:|
|  https | 暗号化されたhttp通信を表すスキーム  |
|  malito |  電子メールの宛先を表すスキーム |
|  ftp  |  FTP（ファイル転送プロトコル）におる入手を表すスキーム |
|  file |  ファイルシステム中のファイルやディレクトリを参照するためのスキーム |

###ホスト名
ホスト名のWWWはWorld Wide Webの略で「世界中に張り巡らせた蜘蛛の巣」を意味します。
省略されても機能に大きく変化はありません。
###ドメイン名
IPアドレスをわかりやすくするために設定する文字列のこと。
ドメイン名はトップレベルドメイン、セカンドレベルドメイン、サードレベルドメインにわけられます。
####トップレベルドメイン
ドメインの一番最後にあたる`jp`や`com`、`net`にあたり、分野別のドメインや国別に割り当てられたコードがあります。
####セカンドレベルドメイン
ドメインの中で二番目に属しているドメイン。
トップレベルドメインの種類によってどのようなドメインが来るか変わってくる。
トップドメインが`jp`の場合`co（組織）`や`or（非営利法人）`等組織を表すドメインが入る。
####サードレベルドメイン
セカンドレベルドメイン以下に属しているドメイン。
重複がない限り登録者が自由に設定できる。
###ディレクトリ
ディレクトリはサーバー内のフォルダの位置を表しています。
ディレクトリが何層もある場合は`/`で区切ります。
###ファイル名
URLの一番末尾にありURLのゴールになる。
この場合は`index.html`になる。

[参考]
[URLとは？意味やドメインとの違い、構成する要素を徹底解説！](https://ferret-plus.com/8736?page=3)
[URLの基礎（初心者向けにわかりやすく解説）](https://blog.senseshare.jp/url-basic.html)

##HTTPとは
HTTP・・・Hyper Text Transfer Protocol
URLでファイルのありかを示すことができるようになりました。そしてHTTPはそのファイルのやりとりをするためのWebサーバーとWebクライアントが通信を行うためのルール、決まりごとになります。
通信をするには取り決めがないと理解ができません。例えば発光信号にしてもプロトコル（発光の長短の組み合わせで文字を送る）を定めないとただの光の点滅にしか過ぎません。そのためにもWeb上でも取り決めが必要なため誕生しました。

###HTTPレスポンス・ステータス・コード
webサーバーはwebクライアントからのHTTPリクエストを受けてHTTPレスポンスを返します。
このHTTPレスポンスの状態を表したのがHTTPレスポンス・ステータス・コードになります。

#####HTTPレスポンス・ステータス・コードのカテゴリー

| ステータスコード | 意味 | 説明 |
|:-:|:-:|:-:|
|  1xx | Information  | リクエストの処理が継続していることを表す  |
|  2xx | Success  | リクエストが成功したことを表す。  |
|  3xx |  Redirection | リクエストを完了させるためには、さらに動作が必要であることを表す  |
|  4xx |  Client Error | クライアント側に起因するエラーのため、リクエストが失敗したことを表す  |
|  5xx |  Server Error | サーバー側に起因するエラーのため、リクエストが失敗したことを表す  

#####よく目にするステータスコード

| ステータスコード | 意味| 説明 |
|:-:|:-:|:-:|
| 200  |  OK | リクエストが正常に完了したことを表す  |
| 302  | Not Found]  | リクエストされたリソースが一時的に別のURIに属していることを表す  |
| 401  | Unauthorized  |  ユーザー認証に失敗したことを表す |
| 403  |  Forbidden | アクセス権限がないために、リクエストの実行を拒否されたことを表す  |
|  500 | Internal Sever Error  |  サーバー内で処理に失敗したことを表す |

[HTTP レスポンスステータスコード](https://developer.mozilla.org/ja/docs/Web/HTTP/Status)

##IPアドレス
HTTPリクエストでリクエストを受けたwebサーバーはURLをもとに目当てのファイルを探してきていました。
このときホスト名がURLで表されていましたが、このホスト名はあくまで人間にわかりやすいように表現されているだけです。
コンピューターはホスト名を**IPアドレス**によって識別しています。
IPアドレスはピリオドで区切られたそれぞれ256通りの4組の数字で構成されていてその組み合わせは**約43億通り**になります。
IPアドレスはグローバルIPアドレスとプライベートIPアドレス（ローカルIPアドレス）に分けられます。グローバルIPアドレスはインターネット上で唯一のアドレスで重複することがありません。いわば固定電話の電話番号のようなものです。
一方プライベートネットワーク内で使用されるIPアドレスをプライベートIPアドレスといいます。
プライベートIPアドレスはプライベートネットワーク内でのみ使われ、例えると内線番号のようなイメージになります。

####DNS（Domain Name System）
IPアドレスとドメイン名を対応付けたしくみ。いわばインターネットの住所録。
IPアドレスは人間にはわかりにくいため、ドメイン名を利用しています。
DNSはドメイン名とIPアドレスの対応表を持ったコンピューター（DNSサーバー）をインターネット上に配置し、DNSサーバーへの問い合わせがあったならばドメイン名に対応するIPアドレスを返します。

[DNSとは](https://www.nic.ad.jp/ja/basics/beginners/dns.html)
##TCP/IP
ホストへの任意の情報を届ける役割をもつプロトコル。
TCP/IPはIPアドレスをもとにHTTPリクエストなどの情報を**パケット**と呼ばれる小さな単位に分割して送信する。

##ポート番号
コンピューターが通信に使用するプログラムを識別するための番号です。
IPアドレスによって届けられる場所（コンピューター）は指定されましたが、その中のどのプログラムに届けるのかはわかりません。
そのため、どのプログラムに渡すのかを指定するのがポート番号です。
ポート番号はプロトコルごとに異なり、HTTPであれば`80番ポート`が設定されます。
**IPアドレスは住所**、**ポート番号は部屋番号**のような例えがわかりやすいです。

##GETメソッドとPOSTメソッドの違い
WebアプリケーションからWebサーバーへ情報を渡すにはGETメソッドとPOSTメソッドの2つがあります。
両者も同じようですが決定的に違うところがあり、その違いを知っておく必要があります。
###GETメソッド
GETメソッドは**URLの後ろにクエリ文字列でフォームに入力された内容をwebサーバーへと送信する。**
つまりフォームに入力して送信した内容が他人に見えてしまうので、**他人に見られてほしくない内容はGETメソッドで送ってはいけない。**
さらにURLの長さが制限されているものもあるので**送信できる文字数が限られている**。
しかし、URLにパラメーターが含まれているので、パラメーターごとに記憶したり、人に伝えるのに便利なため**ブックマークに保存するときに使われる。**

####クエリ文字列
下の例であれば`?`以降の`hoge=hoge`がフォームに入力されて送信される内容。
さらに値が複数ある場合　`&`で区切られる。

```
http://localhost:8080/index.html?hoge=hoge
```

###POSTメソッド
GETメソッドの場合送信される内容はURLではなく、POSTリクエストのメッセージボディに入れられて送信される。
このことからGETメソッドとは違い**送信する内容は第三者からみることができない**に加えてメッセージボディに含まれるので**文字数の制限を受けない**という利点があります。
なので機密情報や、大量の情報を送る場合はPOSTメソッドを使うことがよいということになります。

[【PHP超入門】HTTP（GET・POST）について](https://qiita.com/7968/items/4bf4d6f28284146c288f#%E5%AE%9F%E9%9A%9B%E3%81%AE%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%81%A8%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9%E3%81%AE%E5%86%85%E5%AE%B9%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B-1)

##HTTPはステートレスなプロトコルとはどういうことか
HTTPは**ステートレスつまり状態を保持しない**ということになります。
状態を保持するステートフルとどう違うかというとステートフルは通信のたびに常にやりとりを覚えていて、ステートレスは毎回やり取りをリセットします。一見ステートフルであるほうが便利そうではありますが、何件ものクライアントの通信をサーバーが保持しクライアントごとに処理をするとサーバーの負担が大きくなってしまうため**多くの処理を返す必要のあるWebサーバーはステートレスであることが適しています。**

##ステートレスであることの問題点
HTTPはステートレスで直前の情報を保持しない通信でした。
そのことでどんな問題が生じてくるかというとリクエストのたびに状態がリセットされ、状態を全く覚えていないので再度同じものを表示することができません。例えるとECサイトの買物かごに商品を入れてもサーバーに商品を入れた状態は保存されないので買い物かごは空っぽであるということがあげられます。

##Cookie
HTTPがステートレスであることの問題を解決するために開発されたのが**Cookie**という仕組みです。
Cookieとはクライアントに保存された内容です。
WebサーバーはWebクライアントが最初にアクセスしてきたときにHTTPレスポンスのメッセージヘッダを利用してCookieを送ります。次回以降同じサーバーに接続するときにWebクライアントはHTTPリクエストにCookieを入れて送ることでWebサーバーは接続してきた相手を識別することができます。
ログイン情報であればログイン処理を行ったあとにWebサーバーはレスポンスヘッダの中のSet-Cookieヘッダ内にユーザーIDやパスワードなどを入れてクライアントに送り返します。そして送られてきたCookieはクライアントに保管され、また同じサーバーにリクエストを送るときに同じCookieが送られるのでユーザー情報の識別ができるという仕組みになります。

##セッション
CookieはHTTPのリクエストヘッダやレスポンスヘッダを利用しているため第三者から個人情報やユーザー情報などの重要な情報を盗まれる恐れがありセキュリティ上大きな問題があります。
そのためより安全に情報を保存するために開発されたのが**セッション**です。
セッション管理においてWebクライアントを識別するための手段が**セッションID＊＊です。
セッションIDはWebサーバーで生成されてCookieに入れられてWebクライアントに送られます。次回以降WebクライアントはセッションIDをリクエストに含めてサーバーに送ることでサーバーはセッションIDをもとにクライアントの状態を復元することができます。
例えるとすると私がWebクライアント、受付のひとがWebサーバーと例えます。
受付で私の個人情報などを伝えたら受付は私に受付番号（つまりセッションID）を渡します。この受付番号は私の個人情報と結びついているのでそれ以降はその番号を見せれば個人の証明ができるような例えになります。
Cookieのように情報そのものをやり取りするのではなく、セッションIDとしてやりとりするのでCookieよりも安全性が高いということになります。


[【PHP超入門】Cookieとセッションについて](https://qiita.com/7968/items/ce03feb17c8eaa6e4672)

##参考書籍
この一冊で全部わかるWeb技術の基本
プロになるためのWeb技術入門