RailsAPIモードとNuxtの組みわせでハマったこと
- 投稿者
- だいそん
フロントとバックエンドで分けて開発する際にクッキー・セッションベースの認証でいつも詰まるのでここに記しておきます。
前提
サーバサイドはRails APIモード。バージョンは下記の通りです。
$ bundle exec rails -v
Rails 6.0.2.1
$ ruby -v
ruby 2.6.4p104 (2019-08-28 revision 67798) [x86_64-darwin18]
フロントはNuxt.js。バージョンは下記の通りです。
$ npx nuxt --version
@nuxt/cli v2.11.0
$ node -v
v12.13.1
TL;DR
下記を対応すればOKです。
Rails側
- CORSの設定をする
api_only
をfalse
にする
Nuxt側
- Proxyの設定をする
具体的手順
1. CORSの設定をする
Railsはlocalhost:3001
で起動、Nuxtはlocalhost:3000
で起動するのでそのままAPI通信しようとするとCORS制約にかかる。
Access to XMLHttpRequest at 'http://localhost:3001/session' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
そのため、まずRails側でCORSの設定をする必要がある。
rack-cors
をインストールする
# Gemfile
gem 'rack-cors'
application.rb
を修正する
# config/application.rb
config.middleware.insert_before 0, Rack::Cors do
allow do
# 許可するドメイン
origins "localhost:3000"
# 許可するヘッダとメソッドの種類
resource "*",
headers: :any,
methods: [:get, :post, :patch, :delete, :head, :options]
end
end
2. Proxyの設定をする
APIを投げる時おそらくこのように投げるはず。
this.$axios.post("/api/v1/session", { session: this.loginForm });
ただ先述の通りフロントとサーバでドメインが違うのでこのままだと
http://localhost:3000/api/v1/session
にリクエスト投げることになってしまう。 それを解消するにはProxyの設定をする必要がある。
@nuxtjs/proxyをインストールする
$ yarn add @nuxtjs/proxy
nuxt.config.jsを修正する
modules: [
'@nuxtjs/axios',
'@nuxtjs/proxy' // 追記
],
// 追記
proxy: {
'/api': {
target: 'http://localhost:3001',
pathRewrite: {
'^/api': '/api'
}
},
},
ここまでの設定でCORSの問題はクリアできるので正常にPOSTができるはず。 ただ、セッションがうまく引き継がれないのでログイン状態が保持できない。(ログイン処理自体はうまくいっているにも関わらずセッションに値が保持されない。)
下記gifのサンプルアプリではログインボタンを押すとログイン処理が行われ、成功するとマイページに飛ぶ実装にしています。マイページではログイン中のユーザーを取得して画面に表示する処理を書いています。 ログイン自体はうまくいってるんのですが、マイページにてログイン中のユーザーが取ってこれてません。
サーバ側でcurrent_userやsessionを覗いてみてもnil。
それを解消するには次のことをやる必要があるらしいです。
3. api_only
をfalse
にする
# config/application.rb
config.api_only = false
これで無事ログインできました。
サンプルリポジトリのリンクも貼っておきます。
バックエンド https://github.com/DaichiSaito/nuxt_example_api
フロントエンド https://github.com/DaichiSaito/nuxt_example_front
誰かのお役に立てれば幸いです。