Передача параметров через 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

Ответ 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') %>