sign_in_and_redirect 在 facebook 身份验证正在召回自己之后

sign_in_and_redirect after facebook auth is recalling itself

我有 omniauth-facebook 可以登录 up/sign。登录后,我想将用户重定向到他们点击 auth 块的页面。我正在使用 sign_in_and_redirect 但它似乎在调用最后一个 url,在本例中是

http://localhost:3000/auth/facebook?callback_url=localhost%2Fauth%2Ffacebook%2Fcallback

所以它一直在做: Redirected to http://localhost:3000/auth/facebook?callback_url=localhost%2Fauth%2Ffacebook%2Fcallback

并且它一直在循环中调用此回调,直到它崩溃。这是 omniauth 控制器:

   def facebook
     generic_callback( 'facebook' )
   end

   def generic_callback( provider )
    @identity = Identity.find_for_oauth env["omniauth.auth"]
    if @identity.user != nil
      @user = @identity.user || current_user
    else
      @user = User.from_omniauth(request.env["omniauth.auth"])
    end

    if @user.nil?
      @user = User.create( email: @identity.email || "" )
      @identity.update_attribute( :user_id, @user.id )
    end

    if @user.email.blank? && @identity.email
      @user.update_attribute( :email, @identity.email)
    end

    if @user.persisted?
      @identity.update_attribute( :user_id, @user.id )
      @user = User.find(@user.id)
      sign_in_and_redirect @user, event: :authentication
      return
    else
      session["devise.#{provider}_data"] = env["omniauth.auth"]
      redirect_to new_user_registration_url
      return
    end
  end

设计帮手:

  def sign_in_and_redirect(resource_or_scope, *args)
    options  = args.extract_options!
    scope    = Devise::Mapping.find_scope!(resource_or_scope)
    resource = args.last || resource_or_scope
    sign_in(scope, resource, options)
    redirect_to after_sign_in_path_for(resource)
  end

路线

  resources :users
  devise_for :users, controllers: { registrations: "users/registrations", sessions: "users/sessions",  :omniauth_callbacks => "users/omniauth_callbacks" }, path: '', path_names: { sign_in: 'sign_in', sign_out: 'logout', sign_up: 'sign_up'}
  match '/auth/:provider/callback', to: 'sessions#create', via: [:get, :post]

如何让它定时登录?

好的,问题来了。此行创建递归:

match '/auth/:provider/callback', to: 'sessions#create', via: [:get, :post]

改为:

get 'auth/facebook/callback', to: 'users/omniauth_callbacks#facebook'

如果您稍微重构 #generic_callback 方法以使用 params[:provider] 而不是 provider 参数,您将能够摆脱对您路线中的 omniauth 提供商:

get 'auth/:provider/callback', to: 'users/omniauth_callbacks#generic_callback'

澄清问题:

在问题中描述的实现中 users/omniauth_callbacks#generic_callback 根本没有被调用。相反,您尝试调用 sessions#create,它用于使用应用凭据(通常是电子邮件和密码)登录用户,而在 omniauth 情况下,应该以特定方式创建和验证用户(通过 generic_callbacksign_in_and_redirect 在你的情况下)。

简单地说:

您不必调用 sessions#create 来创建用户会话,#generic_callback#sign_in_and_redirect 就可以做到这一点。