gpt4 book ai didi

ruby-on-rails-3 - Rails 3 和设计 : authenticating a user while performing a POST action

转载 作者:行者123 更新时间:2023-12-05 01:22:11 24 4
gpt4 key购买 nike

使用 Rails 3.0.6、Omniauth 0.2.0 和 Devise 1.2.1,我遇到了以下情况:

我想为用户提供通过 Facebook 进行身份验证的选项。我有一个使用 Devise 设置的用户系统,我可以使用 Facebook 成功进行身份验证。我花了几个小时尝试为一种特定情况编写我想要的行为:

  • 用户没有登录
  • 用户有一个站点帐户
  • 用户通过 Facebook 进行身份验证

此时我为用户提供了 2 个选择

  • 创建一个帐户(可以是一个没有提供信息的虚拟帐户)
  • 将此 Facebook 身份验证与现有帐户相关联

我对后一个选项有疑问。用户已经通过身份验证,但我仍然需要他使用他的站点帐户登录。我的 AuthenticationsController 中有一个操作会将此身份验证与登录用户相关联。不过,Devise 似乎没有提供一种方法让我在保持相同操作的同时让用户登录。这是我第一次尝试这样做

class AuthenticationsController < ApplicationController
before_filter :authenticate_user!, :only => :auth_link_existing_user

...

def auth_link_existing_user
...
end

但是,使用这种方法,如果用户登录,他们将被简单地重定向到我网站的根页面。我知道我可以更改 Devise 的登录重定向,但这将适用于所有登录。我只希望这种情况有一个单独的重定向。

看完this邮件列表问题,我尝试用我自己的自定义行为扩展 SessionsController:

def create
resource = warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new")
set_flash_message(:notice, :signed_in) if is_navigational_format?
sign_in(resource_name, resource)
if params[:redirect] #new
redirect_to params[:redirect].to_sym #new
else
respond_with resource, :location => redirect_location(resource_name, resource)
end

end

这也行不通。我已经将我的 auth_link_existing_user 路由定义为使用 POST 动词(这看起来很准确)并且重定向只能是 GET。

现在我确实想到了一个解决方案:将 Devise 的 authenticate_user! 帮助器中的代码复制并粘贴到一个新函数中,该函数可以在 Controller 操作中调用而无需重定向。这对我来说似乎不太理想,因为它是代码重复并增加了耦合——改变这种行为的 Devise 或 Warden 更新也会破坏我的代码。

有没有其他人尝试过类似的事情并想出一个更优雅的解决方案?您是否看到了一种更简单的方法来向我的用户提供这种或类似的行为?

更新:对于任何想在最后使用我的肮脏解决方案的人,这就是我所做的:

def auth_link_existing_user
# FROM Devise/sessions/create
resource = warden.authenticate!(:scope => :user, :recall => "registrations#auth_new")
set_flash_message(:notice, :signed_in) if is_navigational_format?
sign_in(:user, resource)

# method defined in Ryan Bates' Railscast for Omniauth w/Devise
current_user.apply_omniauth(session[:omniauth])
current_user.save
end

请注意,此操作必须放在您的 session Controller 中。如果不是,Warden 会给你一个“无效的电子邮件/密码”错误。找到源头是一个非常漫长的调试过程。

有了这个,我在用户通过身份验证后使用登录表单提交此操作。

最佳答案

我喜欢你的解决方案是多么干净,尽管它深入堆栈。

以下是我如何通过遵循 Devise wiki 上的 Devise+Omniauth Facebook 示例来实现类似的东西并修改 facebook 方法以将 session 信息传递给登录表单,如下所示:

if @user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Facebook"
sign_in_and_redirect @user, :event => :authentication

else
session["devise.facebook_data"] = request.env["omniauth.auth"]
redirect_to new_user_session_url
end

然后,在您的情况下,我将检查 session["devise.facebook_data"] 的登录 Controller 操作,提交带有表单的 uid + token 和 apply_omniauth(如果存在)。

关于ruby-on-rails-3 - Rails 3 和设计 : authenticating a user while performing a POST action,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5630059/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com