Rails 设计 Twitter OAuth 重定向到表单以继续 oAuth 注册
Rails Devise Twitter OAuth redirect to form to continue oAuth registration
我已经使用 omniauth-facebook
和 omniauth-google
成功实施了 oAuth,但是我在实施 omniauth-twitter
时遇到了困难,因为它不提供电子邮件地址。
我在 Internet 上搜索了可用的解决方案,一个解决方案指出删除 Devise 的电子邮件验证,但我的应用程序需要电子邮件验证。
我想要的是将用户重定向到一个新表单,用户只需输入一个新的电子邮件地址即可完成他的 oAuth 注册,但我不确定如何 link 它与 oAuth数据来完成注册,因为我在提交表单时遇到错误,因为用户名和密码不能从设计中留空,而该表单中只显示电子邮件。
回调控制器
def twitter
@user = User.from_omniauth(request.env["omniauth.auth"])
if @user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Twitter"
sign_in_and_redirect @user, :event => :authentication
else
session["devise.twitter_data"] = request.env["omniauth.auth"].except("extra")
redirect_to twitter_register_path
end
end
twitter_register_path
包含用户必须填写其电子邮件地址才能完成注册的视图。
用户模型
def self.from_twitter_omniauth(auth,email)
where(provider: auth["provider"], uid: auth["uid"]).first_or_create do |user|
user.provider = auth["provider"]
user.uid = auth["uid"]
user.email = email
user.name = auth["info"]["name"]
user.password = Devise.friendly_token[0,20]
user.remote_poster_image_url = auth["info"]["image"].gsub('http://','https://')
end
end
Twitter 注册表单 (twitter_register_path)
<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :email, required: true,label: false %>
</div>
<div class="signup">
<%= f.button :submit, "Sign up",:class =>"register-button" %>
</div>
<% end %>
尽管 Twitter API 最近允许应用程序为其电子邮件请求额外的权限,但我不确定如何实现。
试试这个解决方案,它会对你有所帮助:
我终于这样解决了。
用户被重定向后,如果是新用户,我们将呈现一个表单TwitterForm
供用户输入电子邮件以完成注册。
接下来,表单将提交给我们指定的自定义操作,在我的例子中,我将其放在 UsersController
下,它将使用 Twitter 会话数据和发送的电子邮件完成注册过程用户输入。
由于 Devise 的某些问题,您不能将操作放在 CallbacksController 中,我不确定为什么会出现错误。
设计回调控制器
def twitter
auth = request.env["omniauth.auth"]
@user = User.where(provider: auth.provider, uid: auth.uid).first_or_create
if @user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Twitter"
sign_in_and_redirect @user, :event => :authentication
else
@form = TwitterForm.new
session["devise.twitter_data"] = request.env["omniauth.auth"].except("extra")
render :layout => 'none'
end
end
用户控制器
def twitter_register
@form = TwitterForm.new(params[:twitter_form])
if @form.valid?
email = params[:twitter_form][:email]
@user = User.from_twitter_omniauth(session["devise.twitter_data"],email)
if @user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Twitter"
sign_in_and_redirect @user, :event => :authentication
else
redirect_to register_path
end
else
render 'callbacks/twitter',layout: 'none'
end
end
TwitterForm
class TwitterForm
include ActiveModel::Model
attr_accessor :email
validates :email, presence: true,:format => { :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/ }
end
用户模型
def self.from_twitter_omniauth(auth,email)
where(provider: auth["provider"], uid: auth["uid"]).first_or_create do |user|
user.provider = auth["provider"]
user.uid = auth["uid"]
user.email = email
user.name = auth["info"]["name"]
user.password = Devise.friendly_token[0,20]
user.remote_poster_image_url = auth["info"]["image"]
end
end
我已经使用 omniauth-facebook
和 omniauth-google
成功实施了 oAuth,但是我在实施 omniauth-twitter
时遇到了困难,因为它不提供电子邮件地址。
我在 Internet 上搜索了可用的解决方案,一个解决方案指出删除 Devise 的电子邮件验证,但我的应用程序需要电子邮件验证。
我想要的是将用户重定向到一个新表单,用户只需输入一个新的电子邮件地址即可完成他的 oAuth 注册,但我不确定如何 link 它与 oAuth数据来完成注册,因为我在提交表单时遇到错误,因为用户名和密码不能从设计中留空,而该表单中只显示电子邮件。
回调控制器
def twitter
@user = User.from_omniauth(request.env["omniauth.auth"])
if @user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Twitter"
sign_in_and_redirect @user, :event => :authentication
else
session["devise.twitter_data"] = request.env["omniauth.auth"].except("extra")
redirect_to twitter_register_path
end
end
twitter_register_path
包含用户必须填写其电子邮件地址才能完成注册的视图。
用户模型
def self.from_twitter_omniauth(auth,email)
where(provider: auth["provider"], uid: auth["uid"]).first_or_create do |user|
user.provider = auth["provider"]
user.uid = auth["uid"]
user.email = email
user.name = auth["info"]["name"]
user.password = Devise.friendly_token[0,20]
user.remote_poster_image_url = auth["info"]["image"].gsub('http://','https://')
end
end
Twitter 注册表单 (twitter_register_path)
<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :email, required: true,label: false %>
</div>
<div class="signup">
<%= f.button :submit, "Sign up",:class =>"register-button" %>
</div>
<% end %>
尽管 Twitter API 最近允许应用程序为其电子邮件请求额外的权限,但我不确定如何实现。
试试这个解决方案,它会对你有所帮助:
我终于这样解决了。
用户被重定向后,如果是新用户,我们将呈现一个表单TwitterForm
供用户输入电子邮件以完成注册。
接下来,表单将提交给我们指定的自定义操作,在我的例子中,我将其放在 UsersController
下,它将使用 Twitter 会话数据和发送的电子邮件完成注册过程用户输入。
由于 Devise 的某些问题,您不能将操作放在 CallbacksController 中,我不确定为什么会出现错误。
设计回调控制器
def twitter
auth = request.env["omniauth.auth"]
@user = User.where(provider: auth.provider, uid: auth.uid).first_or_create
if @user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Twitter"
sign_in_and_redirect @user, :event => :authentication
else
@form = TwitterForm.new
session["devise.twitter_data"] = request.env["omniauth.auth"].except("extra")
render :layout => 'none'
end
end
用户控制器
def twitter_register
@form = TwitterForm.new(params[:twitter_form])
if @form.valid?
email = params[:twitter_form][:email]
@user = User.from_twitter_omniauth(session["devise.twitter_data"],email)
if @user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Twitter"
sign_in_and_redirect @user, :event => :authentication
else
redirect_to register_path
end
else
render 'callbacks/twitter',layout: 'none'
end
end
TwitterForm
class TwitterForm
include ActiveModel::Model
attr_accessor :email
validates :email, presence: true,:format => { :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/ }
end
用户模型
def self.from_twitter_omniauth(auth,email)
where(provider: auth["provider"], uid: auth["uid"]).first_or_create do |user|
user.provider = auth["provider"]
user.uid = auth["uid"]
user.email = email
user.name = auth["info"]["name"]
user.password = Devise.friendly_token[0,20]
user.remote_poster_image_url = auth["info"]["image"]
end
end