この記事を書くにいたるまで
現在Rails6.0とNuxt.jsを使って適当にアプリを作っています。(Nuxtの練習です
RailsはAPIモード、認証にはdevise_token_auth
を使用しており、
Nuxtからaxios経由でpostしてtoken認証を行うアプリになっています。
今回loginをaxiosで行ったのですが、そのresponse(response.headers
)の中に
access-token
やclient
などが格納されていないというトラブルが発生しました。
解決すると「こんなことで…」と思いますが、ほぼ1日ハマってしまったので共有です。
ぶつかった壁
まずnuxt側ですが、以下のようにloginアクションを実装しています。
async login(vuexContext, data) {
await this.$axios.post("/api/v1/auth/sign_in", data)
.then(response => {
console.log(response.headers)
})
.catch(e => {
console.log(e)
})
}
次にrails側ですが、CORS対策としてはrack-cors
を導入しています。
以下corsの設定です。
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins 'localhost:3001'
resource '*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head],
expose: ['access-token', 'expiry', 'client']
end
end
exposeに'access-token', 'expiry', 'client'
を記述しています。
通常だとこれでresponse.headers
内に上記3つの結果が表示されるはずです。
しかし以下のような結果しか表示されませんでした。
headers:
cache-control: "max-age=0, private, must-revalidate"
content-type: "application/json; charset=utf-8"
chrome-devtools => [Network] => Response Headers
を見たところ、
こちらにはaccess-tokenの情報が来ているのですが、
responseというオブジェクトから取り出すことができません。
解決策
調べたところ、rack-corsのissuesにたどり着きました。
するとどうやらRack::Cors
という設定が重複しているようです。
念のためgit grep Rack
を実行したところ、なんとconfig/initializers/cors.rb
が見つかり
そこに同じ設定がありました…(それまでconfig/application.rb
に書いていました)
コメントアウトされていたので重複はしていないはずですが、
そもそもの設定を書く場所が間違っていたことになります。
設定をconfig/initializers/cors.rb
に移行し再ログインしたところ、
うまくheadersに反映されました。
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins 'localhost:3001'
resource '*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head],
expose: ['access-token', 'expiry', 'client']
end
end
結果
headers:
access-token: "VPPrzn2DnJuqJi_uDEI4hg"
cache-control: "max-age=0, private, must-revalidate"
client: "TVmLwY1GM23koi9r9HY17g"
content-type: "application/json; charset=utf-8"
expiry: "1587634926"
おわり