【3ヶ月でFlask基礎固め】 1 . CookieとWebStorageの概要

# 前段 - このシリーズの目標
**KGI**
*Flaskに関する基礎知識を理解し実装できるようになる*
**KPI**
*1 - 3ヶ月でテキストを殆ど見ないで同じアプリを1つ作成する*
*2 - アプリのコードの解説を記事として残す*

### 1 - FlaskとDjangoについて

- 双方PythonによるWEBアプリケーションのプラットフォームである。
#### Django
**何でも入っている大人用のおもちゃボックス**
ログイン機能や認証機能などが標準としてセットされている。

#### Flask
**カスタマイズしながら作れるレゴブロックバケツ**
最低限の機能(ルーティングなど)が使えるが
複雑な機能を実装するには外部ライブラリを使う必要がある。

### ○有名なプロダクト
#### Django
- YouTube / Instagram / Pinterest / Spotify / Dropbox(ソース 'https://stackshare.io/django')
#### Flask
- Reddit / Netflix (ソース 'https://stackshare.io/flask')

### 2 - なぜ僕がFlaskを選んだか?
理由は3点。
<details><summary> 1 - Djangoで挫折した経験がある </summary>

```t
実は過去にDJangoを使ったWebAppの学習を1年ほど行ったが無事に挫折をしました。
原因は、Djangoの学習には、Webサービス全般の必要最低限以上の知識が必要だったためなのと
キャリアの方針が定まっていなかったためです。
今は作りたいもの。なりたい自己像が出来上がってきたので、再挑戦という形です。頑張るぞ!!!```
```
</details>

<details><summary>2 - 学習コストが低いため</summary>

```t
Flaskはシンプルな基盤の中で必要な機能を調べて実装するだけで良いので
Djangoの様に必要以上の情報収集を行わないで済むと考えました。
もちろん、将来的にはチーム体制での開発も検討しているのでDjangoへの再挑戦も一応視野にはあります。。。
```
</details>

<details><summary>3 - 作りたいものが実現できるとわかった</summary>

```text
私が作成したいものはスマートフォンとPCを両方跨いだプラットフォームです。
海外と日本の言語の壁を超えて仕事を探せるようなプラットフォームを作成してみたいと考えています。
　
今はそれだけ。
そしてFlaskはバックエンド。フロントにはFlutterを使えば十分に実装できるということがわかりました。
(ChatGPTとの壁打ち議論 haha)
```
</details>

# 本題　: Flaskの基礎部分
:::note
当記事で紹介するプログラミング教材に関して、以下のテキストを参考にさせていただいております。また、原文のコードに若干の変更を加えたバージョンをご紹介いたします。皆様にとって有益な情報を提供できるよう努めてまいります。

**Pythonではじめる Webサービス&スマホアプリの書きかた・作りかた**
https://amzn.asia/d/dWiFwe9
:::

### CookieとWebStorageの概要

WEBサービスにおいてクライアントとサーバーはHTTPプロトコル通信を行う
HTTPプロトコル通信はステートレス(一方通行)となっていて
WEBサーバーはユーザの情報を保存できない

つまり、サーバー単体ではユーザ別の動的なコンテンツを表示できない
そこで、必要になるのがCookieやWebStorageといった方法
両方ともユーザのPCにデータを保存する方法である

#### Cookie : 
4KB保存。HTTP通信のヘッダに情報を乗せてサーバーがクライアントに保存させる方式。
有効期限がある

#### WebStorage : 
5~10MB保存(ブラウザに依存)。JSを使って任意のタイミングで保存される。
新しいHTML5を使うので新しいブラウザにしか使えない
有効期限がない(LocalStorage/SessionStorageで違いがある)


##### 【Cookie】同一生成元ポリシー
Cookieで扱われる情報は同じドメインでなければならないというルールに基づいて扱われます。

例えば、
https://www.mafin.com で生成されたCookieの情報は、
次のサーバーに対しては使うことができません。
http://www.mafin.com -> スキーム(通信プロトコル)が異なる
https://www.pafin.com -> ホスト(ドメイン名)が異なる

Cookieの情報を使うためには以下の情報が一致している必要があります
1. ホスト名
2. スキーム
3. ポート番号

#### 筆者が体験したCookieの不思議

一方、ポート番号が異なるウェブサーバー間で同じCookie情報にアクセスすることができた事例があります。

```python:app.py
from flask import Flask, render_template, redirect
from flask import make_response, request
from datetime import datetime

app = Flask(__name__)

@app.route('/')
def index():
    # Cookieの値を取得
    cnt_s = request.cookies.get('cnt')
    if cnt_s is None:
        cnt = 0
    else:
        cnt = int(cnt_s)
    # カウンタに1加算
    cnt += 1
    response = make_response("""<h1>訪問回数 :{}回</h1><br><p>最新のアクセス日付 : </p>""".format(cnt))
    
    expires = int(datetime.now().timestamp()) + max_age
    response.set_cookie('cnt',value=str(cnt),
                        expires=expires)
    return response

if __name__ == '__main__':
    app.run(host='0.0.0.0',port=5001,debug=True)
```

このコードを　```flask run``` で実行した時のポート番号(5000)と,```python app.py```で実行した時のポート番号(5001)とで同じCookieカウントが表示されてしまったのです。

#### 考察
##### 1.ブラウザが特定の条件下では同一生成ポリシーを緩めている
ブラウザはlocalhostからのアクセスと特例としている場合があるらしく、今回は同じくlocalhostへのアクセスだったため、Cookie情報へアクセスできたのではないかと推察しています
#### 2.CookieのDomain属性
CookieにはDomain属性というパラメータがあり、これを指定していなかったため、同一のCookieリソースにアクセスできたことも考えられます。

#### まとめ
特例はあるものの基本的にはCookie情報は同一生成元ポリシーに基づいたルールが形成されている。任意で別ドメインのCookieを共有させることもできそうだが、これは別サイトから悪意を持ったCookie情報を使った不正アクセスにも繋がるので属性設定は気をつけないといけない。基本的にアプリごとにドメインを分け他方がいい