経緯
先日学校課題をReactを用いてAPIサーバとして作成していました。
学校としてはJavaを使用した課題だったため、やむを得なくServletとTomcatを用い制作していましたがFetchでクッキー等を扱った受け渡し処理をする盛大にハマって4日間ぐらい座学を挟んだので纏めておこうと思います。
なぜハマったのか
このような形で、やり取りを試みたわけですがFetchAPIを検索し__credentials__が自分の頭では理解ができなかったのでハマってしまいました。
そもそもCORSって?
オリジン間リソース共有 (CORS) - MDN web docs
CORS(Cross-Origin Resource Sharing)について整理してみた - Developers.IO
Cross-Origin Resource Sharing(CORS)を使用したHTTPリクエスト
こいった座学は得意じゃないのです。
同一生成元ポリシーをあえて無視する以上、悪意を持った第三者からの攻撃を受けるリスクが高くなる可能性があります。
こうした状況の中で、より手軽に、より安全にクロスドメインアクセスを実現したいという要求に応えるために作られたのがCORSです。
Developers.IO
詰まる話セキリュティ的にマズいのであえて制限をかけ、一部開放する形にしているらしいです。
HTTPプロトコルの__ヘッダー情報を書き換える__必要があるらしいです。
実践編 Tomcatを許可しよう。
サーバー側
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
// 許可したいドメインの追加
res.setHeader("Access-Control-Allow-Origin", "http://192.168.44.55:3000");
// 認証情報やCookieのやりとりをする際にはCredentialsをTrueにする必要がある。
res.setHeader("Access-Control-Allow-Credentials","true");
// 実行可能なHTTPメソッドの追記
0 res.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, DELETE, OPTIONS");
// よくわからないけど追記
res.setHeader("Access-Control-Allow-Headers", req.getHeader("Access-Control-Request-Headers"));
}
注意点
Fillterに記述するように書きましたが、本来はServletに記載すべき項目です。(HttpServletRequest,Responseのため)
クライアント側
fetch(
"URL",{
// クロスドメインのため、modeをcorsに設定
mode:'cors',
// セッションなどを保持する
credentials: "include"
}
}
)
credentialsの設定項目
- mit:決してクッキーを送信しない。
- same-origin:URL が呼び出し元のスクリプトと同一オリジンだった場合のみ、クッキーを送信する。
- include:クロスオリジンの呼び出しであっても、常にクッキーを送信する。
今回したい事は__include__による実装です。
ここでハマりポイント
自分のしていた設定
res.setHeader("Access-Control-Allow-Origin", "*");
エラーログで流れますがワイルドカードは選択するとfetch側で弾かれます。
尚且つ
res.setHeader("Access-Control-Allow-Credentials","true");
を設定しておらず、永遠とクッキーが取得できないまま悶々としていましたが、こういったしょうもない部分でハマりますので座学はやっぱり結構大事だなと思いました。