大参考にさせていただきました
ajaxのPOST送信で403が返却される場合の対処方法
###環境
spring boot
spring security
thymeleaf
###SpringSecurityを使っているときはCSRFトークンが必要
SpringSecurityを使ってログイン機能を作った場合、そのアプリケーション全体でCSRF対策が有効になる
すごくシンプルに言うと、
POSTメソッドを使うときは、入力データだけじゃなくてCSRFトークンも送らないとアクセス禁止になる!
###th:actionでトークンが自動で挿入される
Ajaxじゃなくて普通にformで画面遷移する場合は、
<form th:action="@{hoge}" method="post">
</form>
のように書けば
<form action="/login" method="post">
<!-- Spring MVCの機能と連携して出力されたCSRFトークン値のhidden項目 -->
<input type="hidden"
name="_csrf" value="63845086-6b57-4261-8440-97a3c6fa6b99" />
<!-- omitted -->
</form>
超便利!!
###でもAjaxのときは自動で生成されず、Forbiddenが返ってくる
chromeのデベロッパーツールでヘッダーを確認してみると、
403のステータスコード。アクセスしたらアカンって言われてる。
俺がええって言うてんのに!
SpringSecurityが勝手に「だってCSRFトークンないからあきまへん」って頑なになっとるんですな。
###CSRFトークンを手動でAjaxのヘッダーにセットする
// htmlファイルの最後にCSRFをセット
// ちょっと変な場所
</body>
<meta th:name="_csrf" th:content="${_csrf.token}"/>
<meta th:name="_csrf_header" th:content="${_csrf.headerName}"/>
</html>
</body>
の直前だとエラーになります。
ちょっと変な場所だけど、ここじゃないとダメでした
<head>
の中に書いても読み込まれません
テンプレートエンジンを利用している場合、layoutファイルに次の様な書いてある場合は、個別のhtmlファイルにmetaを挿入しても読み込まれない
<head xmlns:th="http://www.thymeleaf.org"
th:fragment="base_header(title, scripts, links)">
base_header(title, scripts, links)
この部分で、個別のファイルで<head>
の中に書いてある
title
script
link
は読み込めるようになっている
が
metaはない → headにmetaを追加してもCSRFトークンはセットできない
###postで403が返ってきたらCSRFトークンが送信できているか確認しよう!
これほんと初歩でしょうけど。
これで丸一日かかってしまいました。。。