Подтвердить что ты не робот

Как отправить заголовки CORS с помощью Devise, если пользователь не авторизовался (ответ 401)

Я работаю над приложением, где сервер и клиент, потребляющий api, находятся в разных доменах, поэтому я хотел бы использовать CORS. Чтобы сделать это, я должен установить соответствующие HTTP-заголовки в ответе сервера:

def cors_set_access_control_headers
  headers['Access-Control-Allow-Origin'] = 'http://localhost'
  headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
  headers['Access-Control-Allow-Headers'] = '*, X-Requested-With, X-Prototype-Version, X-CSRF-Token, Content-Type'
  headers['Access-Control-Max-Age'] = "1728000"
end

Этот метод используется как before_filter в ApplicationController.

Для некоторых ресурсов пользователь должен пройти аутентификацию и авторизацию. Запросы выполняются через XHR/Ajax. Поэтому, если пользователь не аутентифицирован Devise, он отправит ответ 401 клиенту вместо перенаправления на страницу входа. Но фильтр для установки заголовков CORS не используется для этого ответа. Таким образом, ответ 401 не отправляется клиенту. Я хочу поймать и использовать ответ 401 в клиенте.

В настоящее время я использую обходной путь, не используя методы проверки Devise, но настраиваемый фрагмент файла:

def authenticate_cors_user
  if request.xhr? && !user_signed_in?
    error = { :error => "You must be logged in." }
    render params[:format].to_sym => error, :status => 401
  end
end

Это также устанавливается как before_filter в ApplicationController. Таким образом, фильтр для установки заголовков CORS запускается, и все работает нормально.

Я бы предпочел использовать поведение Devise по умолчанию, но заголовки CORS должны быть установлены в ответе 401. Как это сделать? Должен ли я настроить warden для этого?

Как можно настроить заголовки CORS для ответа 401, сгенерированного Devise, вместо создания собственного ответа?

4b9b3361

Ответ 1

Я успешно использовал драгоценный камень rack-cors https://github.com/cyu/rack-cors и изложил свой опыт на мой блог.

Punchline: укажите порядок промежуточного слоя, чтобы обработчик cors находился перед начальником:

config.middleware.insert_before Warden::Manager, Rack::Cors

Ответ 2

Мы вообще не любили заголовки CORS. Мы предпочитаем использовать HAProxy для перенаправления.

С помощью HAProxy вы можете настроить все запросы, поступающие на сайт website.com/api/, чтобы быть внутренне перенаправленными на вашу машину с рельсами.

frontend main *:80
  acl api      path_beg  -i /api
  acl app      path_beg  -i /app
backend app_backend
  reqrep    ^([^\ ]*)\ /app/(.*)  \1\ /\2
  balance   roundrobin
  server    app_files smartphoneapp.localhost:8000
backend api_backend
  reqrep    ^([^\ ]*)\ /api/(.*)  \1\ /\2
  balance   roundrobin
  server    app_api localhost:3000