使用带有design和rails 5的omniauth-twittergem



我开始观看Ryan Bates关于如何使用带设备的Omniauth的教程(rails cast 235修订版(。我的user.rb文件有问题。他在教程中显示的内容

devise :omniauthable, # ...
def self.from_omniauth(auth)
where(auth.slice(:provider, :uid)).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.username = auth.info.nickname
end
end
def self.new_with_session(params, session)
if session["devise.user_attributes"]
new(session["devise.user_attributes"], without_protection: true) do |user|
user.attributes = params
user.valid?
end
else
super
end
end
def password_required?
super && provider.blank?
end
def update_with_password(params, *options)
if encrypted_password.blank?
update_attributes(params, *options)
else
super
end
end

对我不起作用,它显示了一个ActiveModel::ForbiddenAttributesError,并突出显示了这行代码where(auth.slice(:provider, :uid)).first_or_create do |user|。我认为他的版本不起作用,因为我使用的是Rails5。无论如何,我已经尝试过修改user.rb文件。使用以下代码。

def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
	user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
user.provider = auth.provider
user.uid = auth.uid
token = auth.credentials.token,
secret = auth.credentials.secret
end
end
def self.new_with_session(params, session)
super.tap do |user|
if data = session["devise.twitter_data"]
# user.attributes = params
user.update(
email: params[:email],
password: Devise.friendly_token[0,20],
provider: data["provider"],
uid: data["token"],
token: data["credentials"]["token"],
secret: data["credentials"]["secret"]
)
end
end
end
def password_required?
super && provider.blank?
end
def update_with_password(params, *options)
if encrypted_password.blank?
update_attributes(params, *options)
else
super
end
end
end

我可以让twitter验证页面显示大约一分钟的负载,然后重定向回我的用户注册页面,而无需登录,也不会显示任何错误消息。顺便说一下,有人知道如何使用设备登录facebook吗。

问题与传递给self.from_omniauth(auth)的属性auth有关。您应该在服务器日志上设置一个binding.pryputs auth,以便查看此变量的样子。。

可能当self.from_amniauth(auth)方法运行这个auth.slice()时,它在错误中运行

此外,first_or_create方法可能正在创建一个用户,您可能遗漏了一些内容,从而引发错误。所以试着用调试显示使用user.errors.full_messages

听到的想法是,该方法旨在找到或创建User。它是从控制器动作Users::OmniauthCallbacksController#facebook调用的

request表示这是从服务器到facebooktwitter的传出request。。

Facebook或Twitter将用AJAX response回复此request,其中将包括验证用户所需的信息。

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
# You need to implement the method below in your model (e.g. app/models/user.rb)
@user = User.from_omniauth(request.env["omniauth.auth"])
if @user.persisted?
sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?, you probably saved the env variable
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
def failure
redirect_to root_path
end, you probably saved the env variable
end

然后使用下面的方法where(provider: auth.provider, uid: auth.uid).first_or_create,您将从数据库中创建userfind。问题是,你可能写错了这个方法,或者用错误的参数调用了它,或者你没有用twitter设置api来正确工作。。。

来自https://github.com/plataformatec/devise/wiki/OmniAuth:-概述

这个动作有几个方面值得描述:

OmniAuth从Facebook检索到的所有信息都可以在请求.env["OmniAuth.auth"]时作为哈希获得。查看OmniAuth文档和每个OmniAuth Facebook gem的自述文件,了解返回的信息。

找到有效用户后,可以使用两种Devise方法之一对其进行登录:sign_in或sign_in_and_redirect。正在传递:event=>:身份验证是可选的。只有当您希望使用典狱长回调时,才应该这样做。

也可以使用Devise的默认消息之一设置闪烁消息,但这取决于您。

如果用户没有持久化,我们将OmniAuth数据存储在会话中。注意,我们使用";设计"作为密钥命名空间。这是有用的,因为Devise删除了以"0"开头的所有数据;设计"每当用户登录时,我们都会从会话中清除,因此我们会自动清理会话。最后,我们将用户重定向回我们的注册表格

在定义了控制器之后,我们需要在我们的模型(例如app/models/user.rb(中实现from_omniauth方法:

def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
user.name = auth.info.name   # assuming the user model has a name
user.image = auth.info.image # assuming the user model has an image
# If you are using confirmable and the provider(s) you use validate emails, 
# uncomment the line below to skip the confirmation emails.
# user.skip_confirmation!
end
end

此方法尝试通过提供程序和uid字段查找现有用户。如果没有找到用户,则会使用随机密码和一些额外信息创建一个新用户。请注意,first_or_create方法在创建新用户时会自动设置provider和uid字段。第一个_or_create!方法的操作类似,只是如果用户记录未通过验证,它将引发异常。

最新更新