Devise/Omniauth - 如何处理不包含电子邮件的提供商
我有一个 Rails 应用程序,它使用 Devise 和 Omniauth 来处理身份验证。按照规定,我在omniauth_callbacks_controller中收到来自提供商的回调,我在其中检查身份验证是否已经存在,以及具有提供商提供的电子邮件的用户是否已经存在,如有必要,创建一个新用户。
我需要为每个用户提供一个有效的电子邮件。我的问题来自 Twitter 的回调。 Twitter 不为其用户提供电子邮件,因此我无法创建有效用户。为了解决这个问题,我将提供商的数据存储在会话中,并向用户发送新的注册页面,要求他们提交电子邮件地址,以便我可以创建有效的用户。当提交此表格时,我遇到了问题。该表单已创建一个新用户,但完全有可能具有该电子邮件的用户已经存在(在这种情况下,我需要向该用户添加身份验证)。
目前我正在检查是否已经存在与新用户具有相同电子邮件地址的用户。如果是这样,我将忽略新用户并将身份验证应用于已存在的用户。然而这感觉真的很hacky。
我应该怎么做?
class Users::RegistrationsController < Devise::RegistrationsController
def build_resource(*args)
super
if session[:omniauth]
#If a user with this email already exists then use them instead
existing_user = User.find_by_email(@user.email)
if(existing_user)
existing_user.email = @user.email
@user = existing_user
end
#If there is a session available, we know it contains data for adding an authentication
@user.apply_omniauth_data_as_authentication(session[:omniauth])
#Ensure validations are passed on to next page
@user.valid?
end
end
I have a Rails app that uses Devise and Omniauth to handle authentications. As prescribed I am receiving callbacks from the providers in my omniauth_callbacks_controller, where I check if the authentication already exists, and whether a user with the email given by the provider already exists, creating a new user if necessary.
I need a valid email for each user. My problem comes with callbacks from Twitter. Twitter doesn't provide an email for its users, so I can't create a valid user. To solve this I store the provider's data in a session and I send the user the new registrations page, asking them to submit their email address so I can create a valid user. When this form is submitted I hit a problem. The form has created a new user, but it is perfectly possible that a user with that email already exists (in which case I would need to add the authentication to that user).
At the moment I am checking to see if a user with the same email as the new user already exists. If so, I am ignoring the new user and applying the authentication to the user that already exists. However this feels really hacky.
How should I be doing this?
class Users::RegistrationsController < Devise::RegistrationsController
def build_resource(*args)
super
if session[:omniauth]
#If a user with this email already exists then use them instead
existing_user = User.find_by_email(@user.email)
if(existing_user)
existing_user.email = @user.email
@user = existing_user
end
#If there is a session available, we know it contains data for adding an authentication
@user.apply_omniauth_data_as_authentication(session[:omniauth])
#Ensure validations are passed on to next page
@user.valid?
end
end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
干得好。我会尝试记住我从哪里获得修复并发布链接(如果有):
Here you go. I'll try and remember where I got the fix from and post a link if I do:
我喜欢此链接使用的解决方案 http: //www.orhancanceylan.com/rails-twitter-and-facebook-authentications-with-omniauth-and-devise/
它使用提供者凭据在普通设备中注册进程(以及填写用户或单独表上的提供者和 uid 属性)。因此,当新用户尝试使用提供商注册时,他们将被要求输入电子邮件和密码,从而减少日后的麻烦(例如想要以正常方式登录,但没有密码输入,然后你必须处理这个问题)。
虽然这种解决方案在某种程度上否定了首次在社交媒体上注册的便利性,但它以最小的努力创造了长期的有益效果。
如果您绝对不想要这种要求,因为担心失去注册或让您的网站看起来不够精致,请找到另一个解决方案并完成所有工作来处理这些下游案例。
I like the solution used by this link http://www.orhancanceylan.com/rails-twitter-and-facebook-authentications-with-omniauth-and-devise/
It uses the provider credentials to register in the normal devise process (as well as filling out provider and uid attributes on the user or on a separate table). Thus, when a new user tries to register using a provider, they will be required to put in an email and password, creating less headaches down the road (like wanting to log in the normal way, but not having a password to type in, and then you having to handle that).
While this solution somewhat negates the convenience of registering with social media the FIRST time, it creates long term beneficial effects with minimal effort.
If you absolutely do not want this kind of requirement for fear of losing signups or having your website seem less polished, find another solution and do all the work to handle those downstream cases.