Хорошо, значит, есть проблема с решением Криса Хилда, если вы используете OmniAuth в сочетании с Devise .Проблема в том, что когда вы перезагрузите окно (то есть на странице входа в систему), Devise перенесет вас в root_path, полностью игнорируя URL, к которому вы пытались получить доступ, и выдаст сообщение об ошибке «Вы уже вошли в систему».Это имеет смысл, поскольку Devise защищает вошедшего в систему пользователя от доступа к странице входа в систему путем перенаправления на домашнюю страницу.Перезагрузив страницу входа сразу после входа, вы столкнетесь с этой проблемой.
Поэтому мое решение для кого-то, использующего Devise , заключается в следующем:
# add this wherever needed in your_authentications_or_callbacks_controller.rb
sign_in user
@after_sign_in_url = after_sign_in_path_for(user)
render 'callback', :layout => false
Обычно, после нахождения или создания пользователя с использованием хэша, возвращенного определенным провайдером (Facebook, Twitter и т. Д.), Мы вызываем функцию Devise sign_in_and_redirect
.Но мы пока не можем перенаправить (помните, сейчас пользователь находится во всплывающем окне), поэтому мы просто sign_in
пользователь.
Далее нам нужно передать URL, которым был пользовательпытаясь получить доступ к представлению, и мы можем получить этот URL, используя метод Devise after_sign_in_path_for
.
Наконец, нам нужно визуализировать представление.Поскольку мы будем использовать представление только для вызова некоторого JavaScript, визуализация макета не требуется, поэтому мы отключаем его, чтобы не замедлять работу.Вот это представление:
# views/your_authentications_or_callbacks/callback.html.erb
<script type="text/javascript">
window.opener.location = '<%= @after_sign_in_url %>';
window.close();
</script>
Таким образом, пользователь перенаправляется на правильный URL-адрес после входа в систему и отображается правильное флэш-сообщение.
С отключенным JavaScript
ПослеПосле некоторого тестирования я понял, что это решение не разрешает аутентификацию без JavaScript, поэтому я хотел бы добавить приложение.
function popupCenter(linkUrl, width, height, name) {
var separator = (linkUrl.indexOf('?') !== -1) ? '&' : '?',
url = linkUrl + separator + 'popup=true',
left = (screen.width - width) / 2,
top = (screen.height - height) / 2,
windowFeatures = 'menubar=no,toolbar=no,status=no,width=' + width +
',height=' + height + ',left=' + left + ',top=' + top;
return window.open(url, name, windowFeatures);
}
Изменение здесь заключается в добавлении простого параметра popup
в URL с использованием JavaScript,OmniAuth будет любезен хранить любые параметры запроса, добавленные в URL запроса.Итак, наконец, мы проверяем этот параметр в контроллере.Если он существует, это потому, что включен JavaScript:
if request.env['omniauth.params']['popup']
render 'callback', :layout => false
else
redirect_to @after_sign_in_url
end
Также не забудьте сделать то же самое для вашего действия failure
, которое вызывается, когда пользователь не принимает вход в систему.
Я бы не смог сделать это без решения Криса Хилда, так что ... Большое спасибо!