0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Vercelでsessionを使う(Python Flask)

Posted at

VercelでAPIを作成

Reactを扱うAIのv0にはまりBlueSkyの画像検索サイトを作っていました。
実行環境としてv0の開発元のVercelにフロントエンド、BlueSkyのデータを取得するAPI共にデプロイしようとしました。(APIは別プロジェクトとしてPythonでサーバレスファンクションとして作成しました)

で困ったのはFlaskのsessionに保存ができないことです。このサンプルを起動して振り出されたURLにアクセスすればrequest_countが増えるはずですがjavascriptからfetchで呼び出すと増えないまま。sessionが扱えてないことがわかりました。

server.py(session確認サンプル)
from flask import Flask, jsonify, session
from flask_cors import CORS
from datetime import timedelta

app = Flask(__name__)
app.secret_key = "abcde"
app.permanent_session_lifetime = timedelta(minutes=30)

CORS(app, supports_credentials=True)

@app.route("/", methods=["GET"])
def return_media():

    if not session.get("request_count"):
        session["request_count"] = 1
    else:
        session["request_count"] += 1

    return_data = {"request_count" : session["request_count"]}

    return jsonify(return_data)

if __name__ == "__main__":
    app.debug = True
    app.run(host="0.0.0.0", port=5000)

※以下のように直接アクセスすればうまく行くのですが、ブラウザからfetchで呼び出すとrequest_countは1のまま。

スクリーンショット 2025-02-27 222515.png


これを解消すべく「Vercel session」検索してみると以下の記事が出てきました。


なるほど独自ドメインを設定すればいいのか…とたまたまXserverで持っていたドメインを設定。これで解決のはずがやっぱりsessionには保存できないまま。

また振出しに戻りGoogle ChromeのDevツール(検証)とにらめっこした後、解決に到りました。結果を言いますと次のコードを加えています。

app.config.update追加
from flask import Flask, jsonify, session
from flask_cors import CORS
from datetime import timedelta

app = Flask(__name__)
app.secret_key = "abcde"
app.permanent_session_lifetime = timedelta(minutes=30)

+ app.config.update(
+    SESSION_COOKIE_SECURE=True,
+    SESSION_COOKIE_HTTPONLY=True,
+    SESSION_COOKIE_SAMESITE='None',
+ )

CORS(app, supports_credentials=True)

@app.route("/", methods=["GET"])
def return_media():

    if not session.get("request_count"):
        session["request_count"] = 1
    else:
        session["request_count"] += 1

    return_data = {"request_count" : session["request_count"]}

    return jsonify(return_data)

if __name__ == "__main__":
    app.debug = True
    app.run(host="0.0.0.0", port=5000)


このエラーがわかったのはDevツールの次の画面でした。
スクリーンショット 2025-02-27 223928.png


Set-Cookieの項目で警告(△に!)が出ていました。これの言う通り SESSION_COOKIE_SAMESITE='None' にした次第です。
ただFlask公式ではこれを推奨していません。


他の言語、Flask以外のフレームワークもCOOKIE_SAMESITE='None'で解決できる場合があるかと思います。
ただセキュリティ的にはまずい場合もありますのですので、利用する際にはご注意下さい。

まとめ

警告にあるように根本的な原因はCORSのようです。CORSをちゃんと理解できていればいいのですがすぐには難しいですね…

あと今さらですがネットの記事を過信しすぎるのは良くないなと思いました。(特にニッチなケースの場合)
まぁAPIでセッションを使うというのが本来の使い方じゃないのかもしれませんが…

IT開発は言語・フレームワークなどで状況は無数に変わるので、情報の取得・発信共に気を付ける必要があるようです。

補足

VercelでAPIを作るには適当なフォルダ直下にvercel.json、requirements.txtを置いて、あとはapiフォルダの下にPythonのファイル(今回はserver.py)を作り、Flaskか何かでリクエストを処理できるようにします。簡単なサンプルは以下になります。

フォルダ構成
sample_repository
├─ api
│  └─ server.py
├─ requirements.txt
└─ vercel.json
requirements.txt
Flask==3.0.3
Flask-Cors
vercel.json
{
  "rewrites": [
    { "source": "/(.*)", "destination": "/api/server" }
  ]
}

※vercel.jsonのdestinationを起動するファイル名に指定してあげて下さい

あとはこれをGitHubのリポジトリとしてプッシュしてVercelと連携するだけです

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?