Rack::CorsでCORSの設定時の注意

SinatraRailsでCORSの設定をする時に、よくRack::Corsを利用します.
originsメソッドの引数は、可変長引数となっているため、example.comを追加します.

use Rack::Cors do
  allow do
    origins 'www.khasegawa.net', 'example.com'
    resource '*', methods: %i[get]
  end
end

これでリクエストが通るようになりました.

この時のAccess-Control-Allow--Originは、「www.khasegawa.net」からリクエストした場合、https://www.khasegawa.netになり、「example.com」からのリクエストの場合は、https://example.comという期待する値になっていることも確認出来ます.

複数指定した場合は、マッチしたホストが設定されています.

www.khasegawa.netとsub.khasegawa.netを許可する

Rack::Corsでは、引数に正規表現を指定することも出来るので、それを利用します.

use Rack::Cors do
  allow do
    origins /\Ahttps:\/\/(www|sub)\.khasegawa\.net\z/
    resource '*', methods: %i[get]
  end
end

正規表現で指定する場合の注意点としては、セキュリティを考慮し、schemeを含めた完全一致にすることをオススメします.

この時のAccess-Control-Allow--Originは、「www.khasegawa.net」からリクエストした場合、https://www.khasegawa.netになり、「sub.khasegawa.com」からのリクエストの場合は、https://sub.khasegawa.comという期待する値になっていることも確認出来ますね.

正規表現を指定した場合は、マッチしたホストを返却するようになっています.

挙動から分かる注意点

これらから分かることはなんでしょうか.
どれだけ指定しても、Access-Control-Allow-Originに設定される値は、1つなのです.
ということは、どこかでレスポンスをキャッシュすると不都合が出そうです.

これは、READMEのCommon Gotchasに書いてあることからも分かります.
Common GotchasのCachingでは、Rack::Cacheの話しか出ていませんが、要はキャッシュさせないでっていうことですね.

こういうのは、見落としがちだったりするので要注意ですね.