9

STIなしで複数のモデル用にDevise Omniauthを設定する方法はありますか?

学生と教授のモデルがあり、STI を使用したくありませんでしたが、Omniauth を使用した Devise は複数のモデルではうまく機能しないことに気付きました。

.rvm/gems/ruby-1.9.3-p125/gems/devise-2.1.0/lib/devise/rails/routes.rb:384:in `devise_omniauth_callback': Wrong OmniAuth configuration. If you are getting this exception, it means that either: (RuntimeError)

1) You are manually setting OmniAuth.config.path_prefix and it doesn't match the Devise one
2) You are setting :omniauthable in more than one model
3) You changed your Devise routes/OmniAuth setting and haven't restarted your server
4

4 に答える 4

3

こんにちは、私は同様の問題を抱えてここに来て、この解決策に出くわしました。おそらく次の問題を解決するでしょう。私の場合、異なる方法で omniauth を操作する 2 つのデバイス モデルがあります。最初のモデルは、通常のデバイス サインアップまたは omniauth でサインインできるユーザーでした。2 番目のモデルは、通常の方法でサインアップできるアーティストでした。フォームをサインアップしますが、検証済みフィールドである Twitter からの値を認証するためには、まだ omniauth が必要です (有名なユーザーが本当にその男であるかどうかを意味する Twitter プロファイルの小さなチェック)。

だから私が来たとき、私は2つのdevise omniauthableモデルを持つことができず、両方に同じomniauthを使用することに決めました。

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def all
    if artist_signed_in? and session["devise.authorize"] == current_artist.email
      session["devise.authorize"] = nil
      if current_artist.artist_profile.update_from_omniauth(request.env["omniauth.auth"])
        if current_artist.artist_profile.verified
          flash[:notice] = "You were verified"
        else
          flash[:alert] = "Twitter go well but you aren't verified there"
        end
        redirect_to edit_artist_profile_path(current_artist.artist_profile)
      else
        flash[:error] = "We can't connect with #{request.env["omniauth.auth"].provider.titleize.split(" ").first}"
        redirect_to edit_artist_profile_path(current_artist.artist_profile)
      end
    elsif !user_signed_in?
      user = User.from_omniauth(request.env["omniauth.auth"])
      if user.persisted?
        flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => user.provider.titleize.split(" ").first
        user.user_profile.from_omniauth(request.env["omniauth.auth"])
        sign_in_and_redirect user, :event => :authentication
      else
        session["count_errors"] = 0 if session["devise.user_attributes"] == nil
        session["devise.user_attributes"] = user.attributes
        redirect_to new_user_registration_url
      end
    else
      flash[:notice] = "You are already log in #{current_user.email}"
      redirect_to root_path
    end
  end

  def after_omniauth_failure_path_for(scope)
    if artist_signed_in? and session["devise.authorize"] == current_artist.email
      session["devise.authorize"] = nil
      edit_artist_profile_path(current_artist.artist_profile)
    else
      super
    end
  end

  alias_method :twitter, :all
end

最初のケースである通常のユーザーの場合、

elsif !user_signed_in?

通常のプロセスを実行し、すべてがすべてのガイドと同じですが、2 番目のケース (検証済みフィールドとアーティスト プロファイル) では、ランダムな値で小さなセッションを送信します

session["devise.authorize"]

アーティスト プロファイル コントローラーから新しいルートでリンクを呼び出します。

<%= link_to "Verify with Twitter", artist_profiles_integrate_twitter_path %>

セッションをロードし、ユーザーの omniauth ルートにリダイレクトする人

class ArtistProfilesController < ApplicationController
   ...
   def integrate_twitter
      session["devise.authorize"] = current_artist.email
      redirect_to user_omniauth_authorize_path(:twitter)
   end
 end

次に、各クラスで omniauth を操作するためのいくつかのメソッドを定義しました。1 つ目はユーザーを作成し (railscast エピソード「devise-omniauth-revised」に基づいて)、2 つ目はアーティスト プロファイル モデルのフィールドを更新するだけです。after_omniauth_failure_path_for をオーバーライドする必要があります。 (スコープ)、これはログインの失敗のパスを返すだけです。エラー後のパスを変更するのと同じ手法を使用します (たとえば、Twitter との接続に失敗した場合、ユーザーのサインアップ パスにリダイレクトされ、セッションは回避されます)。しばらくの間) 通常の動作を行い、これによりすべてのケースでセッションをクリーンアップできます。

それが役に立てば幸いです、よろしく!

于 2014-04-06T12:28:49.427 に答える
2

現在、Devise の Omniauthable モジュールは複数のモデルでは機能しません。ただし、Omniauthable モジュールは OmniAuth の単純なラッパーにすぎないため、心配する必要はありません。

https://github.com/plataformatec/devise/wiki/OmniAuth-with-multiple-models

于 2015-01-28T13:10:50.623 に答える
1

:omniauthable個人に書くのではなくStudent&と思いますProfessor model。のような3番目のモデルを生成し、それに設定をOmniuser追加する必要があります。:omniauthable

class Student < ActiveRecord::Base
  has_one :omniuser
end

class Professor < ActiveRecord::Base
  has_one :omniuser
end
于 2012-08-20T07:00:15.527 に答える