Rails:Cookie溢出omniauth twitter注册

zac*_*chj 5 twitter facebook ruby-on-rails devise omniauth

我正在使用omniauth让人们注册/登录Facebook并且运行良好!但我想添加omniauth-twitter gem让他们与Twitter联系.

我按照与设置Facebook连接时相同的步骤进行操作:https://github.com/plataformatec/devise/wiki/OmniAuth : -Overview

但是当我注册/进入时,我收到以下错误:

ActionDispatch::Cookies::CookieOverflow in OmniauthCallbacksController#twitter
Run Code Online (Sandbox Code Playgroud)

在以下网址:

http://localhost:3000/users/auth/twitter/callback?oauth_token=HRjON8J4bj9EcbjiELHcpHmSXo0cPd0wCHyuWG8ATZU&oauth_verifier=ZiZb1FAKZmNML1gVu5RKBLEGzbeAPPzC80QCpPDGU
Run Code Online (Sandbox Code Playgroud)

我在类似的帖子上尝试了不同的东西,但没有一个工作:(

这是我的配置:

omn​​iauth_callbacks_controller.rb => app/controllers/omniauth_callbacks_controller.rb

def twitter
    # You need to implement the method below in your model (e.g. app/models/user.rb)
    @user = User.find_for_twitter_oauth(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 => "twitter") if is_navigational_format?
    else
      session["devise.twitter_data"] = request.env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end
Run Code Online (Sandbox Code Playgroud)

user.rb => app/models/user.rb

def self.find_for_twitter_oauth(auth)
  where(auth.slice(:provider, :uid)).first_or_create do |user|
    user.provider = auth.provider
    user.uid = auth.uid
    user.email = auth.info.email
    user.password = Devise.friendly_token[0,20]
    user.name = auth.info.name   # assuming the user model has a name
  end
end

def self.new_with_session(params, session)
    super.tap do |user|
      if data = session["devise.twitter_data"] && session["devise.twitter_data"]["extra"]["raw_info"]
        user.email = data["email"] if user.email.blank?
      end
    end
  end
Run Code Online (Sandbox Code Playgroud)

devise.rb => app/config/initializers/devise.rb

Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, "KEY, "KEYPASSWORD
end
Run Code Online (Sandbox Code Playgroud)

有什么想法有什么不对吗?

Tim*_*Tim 7

正如Michael在评论中所说的那样,你在会话中存储了一个大的哈希,它太大了(你使用的是默认值,CookieStore而cookie只能包含4KB的数据).omn​​iauth提供的哈希值包含了twitter返回的所有数据,这可能相当多.例如,请参阅自述文件:https://github.com/arunagw/omniauth-twitter#authentication-hash

如果你问题中的代码是与twitter登录相关的所有代码,那么看起来你只需要将电子邮件保留在会话中,因为new_with_session代码使用了所有这些.所以你在该行elsetwitter是:

session["devise.twitter_data"] = request.env["omniauth.auth"]
Run Code Online (Sandbox Code Playgroud)

可能是这样的:

session["devise.twitter_data"] = request.env["omniauth.auth"].select { |k, v| k == "email" }
Run Code Online (Sandbox Code Playgroud)

然而与此的主要缺陷是,Twitter的没有为用户返回一个电子邮件地址,以便数据["电子邮件"]总是会nilnew_with_session反正!因此,如果您稍后对Twitter从未返回的电子邮件感兴趣,那么在会话中保留任何内容都是毫无意义的.也许您想要检索一个名称来帮助预填填注册表而不是电子邮件地址.在这种情况下,您可以将其保留在omniauth的哈希值中.如果你想在哈希中保留一些东西,那么你可以做以下的事情,而不是选择它们全部放入会话中.

session["devise.twitter_data"] = request.env["omniauth.auth"].delete_if("extra")
Run Code Online (Sandbox Code Playgroud)

这将删除"额外"嵌套哈希,这可以帮助其他所有其他东西适合会话.

要获得完整的解决方案,您必须考虑混乱的情况,例如与登录Facebook的人打交道,然后登录Twitter并希望使用相同的电子邮件地址并与您系统上的现有帐户合并.

在任何情况下,请注意,如果您使用的是Rails 3,那么会话cookie不会被加密,因此用户或有权访问其计算机的任何人都可以使用您最终保留在Twitter中的任何数据来读取cookie的内容.如果您使用的是Rails 4,则应对cookie进行加密以防止这种情况发生.