У меня есть приложение, которое разделяет контроллеры в зависимости от того, содержит ли запрос поддомен или нет. Доступ к Devise осуществляется из основного домена, то есть lvh.me:5000/login
. При успешном входе в систему клиент перенаправляется в свое «хранилище», которое находится на поддомене customer-store-name.lvh.me:5000
- здесь он может получить доступ к маршрутам, относящимся к его учетной записи, но не может получить доступ к маршрутам, ограниченным основным доменом, таким как маркетинговые страницы или Разработка маршрутов.
Вкл. customer-store-name.lvh.me:5000
У меня есть раскрывающееся меню, содержащее ссылку «Выйти»,
= link_to 'Sign out',
destroy_user_session_url(host: "lvh.me", subdomain: nil),
method: :delete
Не удается выйти из системы, что приводит к ошибке ActionController::InvalidAuthenticityToken
. Ниже приведен вывод, который дополнительно объясняет, что HTTP Origin header (http://customer-store-name.lvh.me:5000) didn't match request.base_url
.
13:37:59 web.1 | Started DELETE "/logout" for 127.0.0.1 at 2020-04-17 13:37:59 -0400
13:37:59 web.1 | Processing by Users::SessionsController#destroy as HTML
13:37:59 web.1 | User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 /*application:Example*/ [["id", 1], ["LIMIT", 1]]
13:37:59 web.1 | HTTP Origin header (http://customer-store-name.lvh.me:5000) didn't match request.base_url (http://lvh.me:5000)
13:37:59 web.1 | Completed 422 Unprocessable Entity in 7ms (ActiveRecord: 0.9ms | Allocations: 2090)
Проблема сохраняется только при выходе; Я исключил session_store
, так как он настроен правильно и работает при регистрации. Тем не менее, я считаю, что это работает, потому что SessionsController < Devise::SessionsController
и RegistrationsController < Devise::RegistrationsController
перенаправляют на поддомен клиентов, и здесь я пытаюсь напрямую сделать запрос кросс-источника. Мне любопытно, как другие обработали выход с Devise на поддоменах в Rails.
cache_servers = ENV.fetch("REDIS_URL") { "redis://localhost:6379/0" }
Rails.application.config.session_store :cache_store,
key: '_example_session',
serializer: :json,
domain: '.lvh.me',
samesite: 'lax',
redis: {
expire_after: 1.week,
key_prefix: 'example:session:',
url: cache_servers
}