LoginSignup
68
49

More than 5 years have passed since last update.

FastAPIでCORSを回避

Last updated at Posted at 2019-04-04

はじめに

FastAPIを使っていてCORSの問題にぶち当たり
2時間ほど詰まってしまったので、他に困っている人に向けて解決方法を残します。

問題のソースコード

問題のソースコードはこのようになっています。
今回は公式でも取り上げられているようなサンプルプログラムを参考に作っています。
https://fastapi.tiangolo.com/tutorial/first-steps/

main.py
from fastapi import FastAPI

app = FastAPI()

@app.get("/users/")
def read_users():
    return {"id": 1, "name": "taro"}

@app.get("/users/{user_id}")
def read_user(user_id: int):
    return {"user_id": user_id}

FastAPIの起動

$ uvicorn main:app --reload --host 0.0.0.0 --port 8000

http://localhost:8000 で待機します

症状

FastAPIが待機しているhttp://localhost:8000に対して
アプリケーションのhttp://localhost:8080からアクセスすると
下記のようなエラーがchromeのコンソール上で確認されました。

Access to fetch at 'http://localhost:8000/users/' from origin 
'http://localhost:8080' has been blocked by CORS policy: 
No 'Access-Control-Allow-Origin' header is present on the requested resource. 
If an opaque response serves your needs, set the request's mode to 
'no-cors' to fetch the resource with CORS disabled.

エラーを見てみるとCORSのポリシーによってhttp://localhost:8080はブロックされているようなので、
どうやらサーバ側でアプリケーションURLを許可するかCORSを回避してあげれば良さそうです。

解決方法

通常であれば、サーバからのレスポンスヘッダーに
Access-Control-Allow-Origin: *を追加してあげればよいのですが、

FastAPIの場合は直接ヘッダー情報を追加するのではなく、下記のような対応をとります。

  • 追記 allow_origins=["*"]のみだと、POSTのとき怒られるので、 3つほどパラメータを追加しました。 これで、全メソッドに対応できると思います(POST,PUTしか検証していません
main.py
from fastapi import FastAPI
from starlette.middleware.cors import CORSMiddleware # 追加

app = FastAPI()

# CORSを回避するために追加(今回の肝)
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,   # 追記により追加
    allow_methods=["*"],      # 追記により追加
    allow_headers=["*"]       # 追記により追加
)

@app.get("/users")
def read_users():
    return {"id": 1, "name": "taro"}

@app.get("/users/{user_id}")
def read_user(user_id: int):
    return {"user_id": user_id}

今回、解決にあたって、こちらの方が実装しているコードを参考にしました。

https://github.com/tiangolo/full-stack-fastapi-postgresql/blob/b96d78db99d8c4f37f0df64df587ffebda4bfc56/%7B%7Bcookiecutter.project_slug%7D%7D/backend/app/app/main.py

おわりに

CORSについてエラーが起きたとき、当初はCORSについてまったく知識がなかったので、どう対処してよいかわかりませんでしたが、フィックスしていくに当たって、理解を深めることができよかったです。ただ、2時間消費してしまったのはつらい...
少しでも他の方のお役に立てればと思います。

68
49
3

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
68
49