Flask と Redis でセッションをサーバーサイドに移す
Flask のデフォルトセッションは Cookie に保存されるが、サイズ制限やセキュリティ上の理由でサーバーサイドに保存したい場合がある。Flask-Session と Redis を使えば、セッションをサーバーサイドに移せる。
Flask-Session のセットアップ
pip install flask-session redisfrom flask import Flask, session
from flask_session import Session
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = redis.from_url('redis://localhost:6379')
app.config['SESSION_PERMANENT'] = False
app.config['SESSION_USE_SIGNER'] = True
Session(app)設定オプション
| SESSION_TYPE | ストレージの種類(redis, filesystem, memcached など) |
| SESSION_REDIS | Redis 接続オブジェクト |
| SESSION_PERMANENT | 永続セッションにするか |
| SESSION_USE_SIGNER | セッション ID を署名するか |
| SESSION_KEY_PREFIX | Redis キーのプレフィックス |
使い方は同じ
サーバーサイドセッションでも、使い方はデフォルトと同じである。
@app.route('/login')
def login():
session['user_id'] = 123
session['cart'] = {'items': [], 'total': 0} # 大きなデータも保存可能
return 'Logged in'
@app.route('/cart')
def cart():
return session.get('cart', {})Cookie との違い
| Cookie セッション | データが Cookie に保存される(約4KB制限) |
| サーバーサイドセッション | Cookie にはセッション ID のみ、データは Redis に保存 |
サーバーサイドセッションではデータサイズの制限が緩和される。
Redis に保存されるデータ
Redis では以下のような形式でセッションが保存される。
redis-cli
> KEYS session:*
1) "session:abcd1234..."
> GET session:abcd1234...
# pickle でシリアライズされたセッションデータセッションの有効期限
from datetime import timedelta
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=7)
@app.route('/login')
def login():
session.permanent = True # これで有効期限が適用される
session['user_id'] = 123
return 'Logged in'Redis の接続設定
本番環境では接続プールを使う。
import redis
redis_client = redis.Redis(
host='localhost',
port=6379,
db=0,
decode_responses=False, # Flask-Session は bytes を期待
socket_timeout=5,
connection_pool=redis.ConnectionPool(max_connections=10)
)
app.config['SESSION_REDIS'] = redis_clientスケールアウト対応
Redis をセッションストアにすることで、複数の Flask インスタンス間でセッションを共有できる。ロードバランサー配下で複数サーバーを動かす場合に必須である。
┌─────────┐
│ Nginx │
└────┬────┘
┌───────┼───────┐
▼ ▼ ▼
Flask 1 Flask 2 Flask 3
└───────┼───────┘
▼
┌───────┐
│ Redis │
└───────┘どの Flask インスタンスにリクエストが来ても、同じセッションにアクセスできる。



