Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
71
Help us understand the problem. What is going on with this article?
@shimpeiws

Rails APIでクロスドメインとpre-flight対応

More than 3 years have passed since last update.

localでRails APIとWebクライアントを別途立てていた時に、クロスドメインとpre-flightへの対応が必要になりました。
Rails APIサーバ: localhost:3000
Webフロントエンド: localhost:3355

Webフロントエンドでは、HTTPクライアントとしてaxiosを利用しました。

クロスドメイン対応

クロスドメイン対応が無い場合、リクエストで"No 'Access-Control-Allow-Origin' header is present on the requested resource." とエラーが出ます

スクリーンショット 2017-03-06 17.46.37.png

localhost:3355からのアクセスに対して、クロスドメイン対応をいれます。

config/application.rb
config.action_dispatch.default_headers = {
  'Access-Control-Allow-Credentials' => 'true',
  'Access-Control-Allow-Origin' => 'http://localhost:3355',
  'Access-Control-Request-Method' => '*'
}

未検証ですが、下記gemではrackレベルで対応可能のようです。
cyu/rack-cors

参考

Rails4アプリに対してクロスドメインでAjaxでCookieを送信したい場合

pre-flight対応

axiosは異なるオリジンに対してリクエストする時に、OPTIONSメソッドでpre-flightのリクエストを送信します。
How to disable OPTIONS request?

OPTIONSメソッドでリクエストしようとして404になります
スクリーンショット 2017-03-06 17.57.59.png

Railsサーバは以下のようなエラーが出ます

Started OPTIONS "/user_token" for ::1 at 2017-03-06 17:57:46 +0900
  ActiveRecord::SchemaMigration Load (3.9ms)  SELECT `schema_migrations`.* FROM `schema_migrations`

ActionController::RoutingError (No route matches [OPTIONS] "/user_token"):

Railsでのpreflightリクエストの実装およびテスト例の実装を参考に実装してみます。

routes.rbの先頭でOPTIONSメソッドでのリクエストに対して、options_requests_controllerをルーティングします。

config/routes.rb
Rails.application.routes.draw do
  match '*path' => 'options_request#preflight', via: :options
  # other resources
end

ヘッダに'Access-Control-Max-Age', 'Access-Control-Allow-Headers', 'Access-Control-Allow-Methods' をつけて返します。

app/controllers/options_request_controller.rb
class OptionsRequestController < ApplicationController
  ACCESS_CONTROL_ALLOW_METHODS = %w(GET OPTIONS).freeze
  ACCESS_CONTROL_ALLOW_HEADERS = %w(Accept Origin Content-Type Authorization).freeze

  def preflight
    set_preflight_headers!
    head :ok
  end

  private

  def set_preflight_headers!
    response.headers['Access-Control-Max-Age'] = ACCESS_CONTROL_MAX_AGE
    response.headers['Access-Control-Allow-Headers'] = ACCESS_CONTROL_ALLOW_HEADERS.join(',')
    response.headers['Access-Control-Allow-Methods'] = ACCESS_CONTROL_ALLOW_METHODS.join(',')
  end
end
71
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
shimpeiws
Ruby, Rails / JavaScript, React, Vue.js / Go / AWS, GCP

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
71
Help us understand the problem. What is going on with this article?