有没有办法在没有 STI 的情况下为多个模型配置 Devise Omniauth?
我们有学生和教授模型,我们不想使用 STI,但现在我们意识到 Devise with Omniauth 不能很好地处理多个模型。
.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
嗨,我来到这里遇到了类似的问题,我遇到了这个解决方案,也许我会帮助下一个。 就我而言,我有两个设计模型,我以不同的方式使用omniauth,我的第一个模型是一个用户,可以使用正常的设计注册或omniauth登录,第二个模型是一个艺术家,他可以使用常规的方式注册注册表格,但我仍然需要omniauth来验证来自twitter的值,已验证字段(对twitter个人资料的小检查意味着著名用户是否真的是那个人)。
所以当我来的时候,我不能拥有两个设计的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?
它将执行正常的过程,一切都像每个指南一样,但对于第二种情况(经过验证的字段和艺术家简介),我发送一个带有一些随机值的小会话
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,第一个创建用户(基于railscast剧集“devise-omniauth-revised”),第二个只是更新我的艺术家个人资料模型上的字段,您应该覆盖after_omniauth_failure_path_for(scope),这只是返回登录失败的路径,使用与更改错误后路径相同的技术(例如,当无法与 twitter 连接时,它将重定向到用户注册路径,并且会话将是大约一段时间)我们可以有正常的行为并在所有情况下清理会话。
希望有帮助,问候!
目前,Devise 的 Omniauthable 模块不支持多个模型。 (https://github.com/plataformatec/devise/wiki/OmniAuth-with-multiple-models) 简而言之,您需要停止依赖设备通过“omniauthable”来发挥其魔力,并手动完成此操作。它并不复杂,一旦你让第一个模型在中间件上工作,那么很明显如何扩展多个模型,因为它归结为完全相同的代码,只是模型名称不同。
所需步骤:
我解决了类似的问题,我在这里有详细的解释:https://kodius.com/blog/devise-omniauth-multiple-models 中间件 oauth 设置的代码在这里:https://github.com/kodius/oauth-example-multiple-models
目前,Devise 的 Omniauthable 模块不支持多个模型。不过无需担心,因为 Omniauthable 模块只是 OmniAuth 的一个简单包装。
https://github.com/plataformatec/devise/wiki/OmniAuth-with-multiple-models
我认为而不是写
:omniauthable
给个人Student
和Professor model
。您应该生成第三个模型,例如 Omniuser
并为其添加 :omniauthable
设置。
class Student < ActiveRecord::Base
has_one :omniuser
end
class Professor < ActiveRecord::Base
has_one :omniuser
end