はじめに
完全に備忘メモになります。自分の苦しんだ時間を忘れないように書いておこうと思いました。
もし同じようにハマっている方がいたら参考なると幸いです。
発生したこと
勉強も合わせて、Next.jsで作ったフロントエンドのアプリからGo(echo)のAPIを使おうとした場合にCORSエラーになり、正しく動きませんでした。
発生当時はCookieだとはわかっておらずなんやかんやで1日溶かしました。。
使用環境
フロントエンド
- Next.js : 13.4.5
- React : 18.2.0
- Axios : 1.4.0
バックエンド
- Go : go1.20.4
- Echo : 3.3.10
やりたかったこと
フロントエンドからバックエンドにリクエストする際にcsrf
というCookieを付与してリクエストすることで、バックエンドは正常に処理してレスポンスを返却します。
Go側ではローカルと特定の環境は許可するように仕込んでいました。PostmanやCurlでのリクエストで疎通も確認できていました。(以下は抜粋です)
.
.
.
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"http://localhost:3000", os.Getenv("FE_URL")},
AllowHeaders: []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept,
echo.HeaderAccessControlAllowHeaders, echo.HeaderXCSRFToken},
AllowMethods: []string{"GET", "PUT", "POST", "DELETE"},
AllowCredentials: true,
}))
e.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{
CookiePath: "/",
CookieDomain: os.Getenv("API_DOMAIN"),
CookieHTTPOnly: true,
CookieSameSite: http.SameSiteNoneMode,
}))
e.POST("/hoge", cc.Hogehoge)
.
.
.
結論
問題はaxiosのリクエスト時にwithCredentialsオプションを設定していなかったことにありました。このオプションが設定されていないと、Cookieが送信されません。
実際に記述した内容は下記のとおりです。
const response = await axios({
withCredentials: true, // ←これを追加
method: "POST",
url: "http://localhost:8080/hoge",
data: data,
})
ちなみにREADME.mdにも説明が記載されていました。
以下withCredentials
について抜粋
// `withCredentials` indicates whether or not cross-site Access-Control requests
// should be made using credentials
withCredentials: false, // default
つまり、CORSを制御するための設定で、デフォルトではfalse(Cookieを送信しない)になっています。
まとめ
初歩中の初歩ですが、公式をちゃんと読めよというお話でした。
痛みを伴って良い勉強になりました。