🍪

キャッシュ・クッキー・セッションの違い

2024/10/11に公開

はじめに

インターン先でWEBアプリのログイン画面作成を任された際に、疑問に思ったことを調べたのでここでアウトプットします!
(もし理解が間違っていれば指摘して頂けると嬉しいです!)

今まであまり意識せずにセッションやクッキーといった言葉を使ってきましたが、いまいち違いが分かっていないな。と思ったので自分なりに調べました!
調べていく中でキャッシュという言葉も登場してきたので、キャッシュも含めた3つの言葉についてまとめています!

クッキー(cookie)について

ユーザのブラウザに保存する約4KBのテキストファイルのこと。

役割

サーバ側がユーザを認識し、過去にそのサイトを訪れたことがある人なら、その個人それぞれに対しての特別な対応をするため。
自動ログインやユーザが過去に閲覧したページの管理など。

保存場所

ユーザーのブラウザ

有効期間

※2種類のクッキーがあり、それぞれのクッキーで異なる。

  • セッションクッキー
    ユーザがブラウザを閉じると消滅する!
  • 永続クッキー
    サーバが永続クッキーをブラウザに作成する際に、有効期限を設定できる。
    有効期限を2週間とすると、二週間後に自動的にブラウザから削除される。

具体的なクッキーの流れ(セッション管理)

  • ブラウザ(クッキー)側

➊ユーザがアクセスした際にサーバがsessionID[1]を発行し、そのsessionIDをクッキーに保存。
その他の情報もクッキーに保存できる。
ただし、クッキー内の情報は改ざんや盗み見されるリスクがあるので、重要な情報は保存するべきではない。
重要な情報をクッキーに保存する際は、HttpOnly(JavaScriptからのアクセスを禁止)や Secure(HTTPSでのみ送信)を設定して、暗号化した通信のみで送受信されるようにすべき。

  • サーバ側(以前にこのサイトを訪れたことがあるユーザーが再び訪問した場合)

➍ユーザのクッキーからsessionIDを取得し、そのsessionIDが有効かどうかを確認。
有効か無効かで、そのユーザに対する処理を変えられる。
sessionIDに基づいて、ユーザの情報をサーバに保存することもできる。
(サーバ側に保存するので容量はほぼ無制限)

セッションについて

Webサイト利用中の状態を管理する仕組み。

役割: ログイン状態やショッピングカートの内容を保持する。
管理方法: セッションクッキーを利用。
有効期間: ブラウザを閉じると消える。
用途例: ログイン状態の維持、ショッピングカートの管理。

キャッシュについて

Webサイトの表示速度を向上させるための一時的なデータ保存機能。

役割: Webサイトの表示を高速化する。
保存場所: ユーザーのブラウザ
有効期間: ブラウザの設定や、サイトの指定による(長期間保存可能)。
用途例: HTMLファイル、画像、CSSファイルなどの一時保存。

セッション管理実装してみる

from flask import Flask, request, redirect, url_for, session

app = Flask(__name__)

app.secret_key = 'your_secret_key'  
# セッションを使用するために必要なシークレットキーを設定
# ここの文字数字列をもとに、暗号化を行っている。ハッシュ化みたいな感じ。

# セッションの有効期限を秒単位で設定(ここでは5分 = 300秒)
app.permanent_session_lifetime = 300

@app.route('/', methods=['GET', 'POST'])
def index():
    # クッキーを持ってなかったらそもそも何の情報も入っていないからここは実行されない。
    # クッキーを持っていた場合は、sessionの値(暗号化されている)それを復元して、
    # その表の中にusernameがあればログイン済みと判定。
    if 'username' in session:
        return 'あなたはログインしたことがあります!'
    
    # POSTリクエスト(ログイン処理)
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        
        # 簡単なユーザー認証の例(本番ではセキュリティ上もっと複雑なものにすべき)
        if username == 'user' and password == 'pass':
            session['username'] = username  
            # セッションに辞書型の配列のようなものを作成し、
            # キー(username)と値(ユーザが入力したユーザー名)を挿入
            session.permanent = True  # セッションに有効期限を設定
            return redirect(url_for('index'))
        else:
            return 'ログインに失敗しました。もう一度お試しください。'
    
    # GETリクエスト(ログイン画面の表示)
    return '''
        <form method="post">
            ユーザー名: <input type="text" name="username"><br>
            パスワード: <input type="password" name="password"><br>
            <input type="submit" value="ログイン">
        </form>
    '''
    # ↑でmethodがPOSTであると指定している。



@app.route('/logout')
def logout():
    session.pop('username', None)  
    # セッションからusernameというキー、そこに格納された値を削除
    return redirect(url_for('index'))

if __name__ == "__main__":
    app.run(debug=True)

どのようなものか

  • Flaskフレームワークを使用して実装されたシンプルなログイン・ログアウト機能を持つWebアプリケーション。
  • ユーザーがフォームに入力したユーザー名とパスワードをセッションに保存し、ログイン状態を維持する。
  • ログイン状態が維持された状態でアクセスすると、あなたはログインしたことがあります! というメッセージが表示される。
  • ログアウト時には、セッションからユーザー名を削除してログアウト処理を行う。また、セッションには5分の有効期限が設定されている。

処理の流れ

  1. 初回ログイン時にセッションデータ({'username': 'ユーザが入力したusername'})をsessionオブジェクトに保存。
  2. サーバーはこのデータを暗号化・署名してクッキーとしてクライアントに送信。
     クッキーに暗号化後の値を入れる際に、自動的にキーとしてsessionという名前が付けられる。
  3. クライアントはこのクッキーをブラウザに保存し、次回のリクエスト時に自動的にサーバーに送信。
  4. サーバー側では、受け取ったクッキーの署名を検証し、セッションデータを復元。
     もしも、悪意のあるユーザで故意にクッキーの中のsessionというキーに格納されている値(暗号化されているので、ぐちゃぐちゃな文字列)を改変していた場合、サーバ側で復元ができない。
     その時点で、クッキーを持っていないユーザと同じ扱いになる。
  5. 復元されたセッションデータを用いて、if 'username' in session: でユーザーがログイン済みかどうかを判定。

最後に

少しはセッション、クッキーについて理解することができたので、これをもとにインターン先のWEBアプリに組み込んでみようと思います!
GoogleFirebaseを用いたログイン機能も簡単に作成できるみたいなので、またよく調べないと。。

冒頭でも申し上げましたが、私の間違いなどございましたら、ご指摘していただけると嬉しいです。
ブログも初心者のため、「この辺りが見にくい」「構成はこうした方が良い」などございましたら、ご教示していただけると幸いです。

最後まで読んでいただき、ありがとうございました!

参考元

脚注
  1. Webサービスにおいてユーザーを一意に識別するために使用される固有のID ↩︎

Discussion