Gem Omniauth,微博与 CookieOverflow

lilu · 2012年12月14日 · 最后由 jevanwu 回复于 2014年11月11日 · 3950 次阅读

在为http://meejian.comdevise 和 omniauth 做微博登录时,犯了一个错误,这里分享一下:

有时候,你需要将 omniauth 返回的 env["omniauth.auth"] 的信息记录下来,然后在用户真正注册的时候把这些信息填充进去,这样用户就不用再填写一些头像姓名之类的信息了

可以使用 session 记录,然后在 user model 里重载 devise 提供的new_with_session方法:

class << self
    def new_with_session(params, session)
      super.tap do |user|
        if data = session["devise.omniauth"]
          user.merge_from_omniauth! data
        end
      end
    end
  end

  def merge_from_omniauth!(data)
    auths << Auth.from_omniauth(data)
    self.name ||= data[:info][:name]
    self.location = data[:info][:location]
    self.description = data[:info][:description]
    self.remote_avatar_url = data[:info][:image]
  end

但是,如果把env["omniauth.auth"]的信息全部记录到session["devise.omniauth"]中,只要是新浪微博做 provider,那么就会出现ActionDispatch::Cookies::CookieOverflow的错误

原因是微博返回的信息中有一个:extra字段,它相当地大,所以造成了 cookie 的溢出 (因为 cookie 只能存有限的数据,通常浏览器是 4k)

解决方法有两个:

  1. 不用 cookie 存储 session 数据,改用数据库或别的内存存储方案
  2. session["devise.omniauth"] = request.env["omniauth.auth"].except(:extra)

顺带一提,除了微博, twitter 的 oauth 返回数据也有这个很大的:extra 字段

所以我在 callback 里把网站需要的字段提取出来 存到 session

有类似的例子吗?

#2 楼 @shiren1118 railscasts 的 devise and omniauth 那期我记得是

业务逻辑可以看看http://meejian.com

遇到这个问题了 非常感谢!!

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册