Передача параметров через OmniAuth
Мне нужно передать некоторые параметры для обратного вызова. Судя по исходному коду, OmniAuth должен добавить строку запроса для обратного вызова, но, как ни странно, это не так. Когда я открываю
/auth/facebook?from=partner
... и перенаправить на Facebook, return_url
- это просто
/auth/facebook/callback
... без каких-либо параметров.
Ответы
Ответ 1
После борьбы со всеми приведенными выше ответами я понял, что делать в отношении Facebook, который по умолчанию не отображает параметры в request.env["omniauth.auth"]
.
Итак - если вы используете строку запроса для обратного вызова, аналогично примерно так:
"/auth/facebook?website_id=#{@website.id}"
Единственный способ получить этот параметр site_id - использовать request.env["omniauth.params"]
. ЗАМЕЧАНИЕ: УБЕДИТЕСЬ, ЧТО ВЫ ИСПОЛЬЗУЕТ omniauth.params, а не omniauth.auth - этот меня немного сработал.
Затем, чтобы проверить это, вы можете проверить его в рамках действия вашего контроллера (обратите внимание на строку RAISE...):
def create
raise request.env["omniauth.params"].to_yaml
# the rest of your create action code...
end
Вы должны увидеть свой параметр там. Отлично. Теперь вернитесь к контроллеру и удалите эту линию RAISE. Затем вы можете получить доступ к параметру следующим образом в действии вашего контроллера:
params = request.env["omniauth.params"]
website_id = params["website_id"]
ПРИМЕЧАНИЕ: в параметрах [ "website_id" ] вам нужно использовать кавычки и НЕ символ.
Ответ 2
Я думаю, что работа с файлом cookie работает, но зачем это делать, когда вы можете использовать переменную состояния, как описано здесь: https://github.com/mkdynamic/omniauth-facebook
Вот как я его использовал:
при создании URL-адреса вы можете просто добавить состояние в строку запроса, и оно также будет доступно в URL-адресе обратного вызова.
user_omniauth_authorize_path(:facebook, :display => 'page', :state=>'123') %>
теперь обратный вызов будет
http://localhost:3000/users/auth/facebook/callback?state=123&code=ReallyLongCode#_=_
Теперь в обработчике обратного вызова вы можете обработать состояние
Ответ 3
Вы можете использовать параметры :params
, как в
omniauth_authorize_path(:user, :facebook, var: 'value', var2: 'value2' )
а затем в обратном вызове вы можете получить доступ к request.env['omniauth.params']
, чтобы получить хэш!:)
(скопирован из этот ответ)
Ответ 4
То, что вы хотите сделать, - это динамически установить ваш обратный вызов, чтобы включить имя партнера в URL-адрес ( не параметры URL-адреса) на основе для каждой транзакции аутентификации, в зависимости от на котором был вовлечен партнер. Это означает, что динамический адрес обратного вызова задается для каждого запроса на аутентификацию. См. этот пост в блоге, чтобы начать работу. URL-адрес обратного вызова автоматически отменяет параметры URL-адреса, как вы заметили, поэтому выполнение этого с параметрами не будет работать.
Итак, если вместо того, чтобы пытаться передать имя /id партнера в качестве параметра (который отбрасывается), вы структурировали свои маршруты, чтобы partner_id
и OmniAuth provider
были частью URL-адреса обратного вызова, тогда вы 'd иметь что-то вроде:
/auth/:omniauth_provider/callback/:partner_id
... где действительный обратный вызов будет выглядеть как
/auth/facebook/callback/123456
... тогда вы бы знали, что данный обратный вызов пришел из facebook, с идентификатором партнера 123456
Ответ 5
OmniAuth уже имеет встроенный способ узнать, где был пользователь, он называется "происхождение", как описано здесь:
https://github.com/intridea/omniauth/wiki/Saving-User-Location
Ответ 6
Знаешь, я думаю, что, возможно, я попытаюсь решить этот трудный путь.
Куки могут быть ответом. Я думаю, вы можете решить эту проблему, указав, что ваш файл входа в систему хранит куки файл, а затем перенаправляется на правильный путь /auth/:provider
для проверки подлинности, и когда обратный вызов запускается (в SessionsController#create
), вы просто читаете файл cookie, чтобы узнать, где перенаправить их.
Итак, прямо сейчас ваша ссылка "login with facebook" (или все, что у вас есть в вашем приложении), вероятно, относится к /auth/facebook
. Вместо этого, если вы создали настраиваемое действие, например
POST /partner_auth
... и вызвал его с помощью url...
POST example.com/partner_auth?from=partner&provider=facebook
Тогда у вас может быть такой контроллер, как:
class PartnerAuth < ApplicationController
def create
cookies[:from] = params[:from] # creates a cookie storing the "from" value
redirect_to "auth/#{params[:provider]"
end
end
Затем в действии SessionsController#create
у вас было бы...
def create
...
destination = cookies[:from]
cookies[:from].delete
redirect_to destination # or whatever the appropriate thing is for your
# app to do with the "from" information
end
Я попытался создать демонстрационное приложение, чтобы выполнить то, что я описал в другом ответе, но вы правы - слишком сложно попытаться динамически вводить пользовательский обратный вызов в код OmniAuth. Существует опция конфигурации для переопределения обратного вызова по умолчанию, но, как представляется, ее легко установить динамически.
Итак, мне стало ясно, что файлы cookie будут проще, специфичны для пользователя, и поскольку вам теоретически нужно хранить эту информацию from
в течение очень короткого времени (между тем, когда пользователь пытается аутентифицироваться, и когда обратный вызов запускается), это не имеет большого значения для создания файла cookie, а затем удаляет его, когда обратный вызов попадает.
Ответ 7
Используйте переменную "состояние". Facebook позволяет пользователю установить переменную STATE.
Вот как я это сделал, я добавил URL AUTH с именем: state = имя_сервера
http://localhost/users/auth/facebook?state=providername
Этот параметр возвращается мне в Callback как params ['providername']
Я разработал решение из оригинального метода пути Omniauth
user_omniauth_authorize_path(:facebook, :display => 'page', :state=>'123') %>