【问题标题】:redirection forbidden / bad uri (facebook) paperclip image重定向禁止/坏 uri (facebook) 回形针图像
【发布时间】:2026-01-24 02:20:03
【问题描述】:

我正在尝试将用户的 Facebook 网址保存到我的数据库中,但出现以下错误。

redirection forbidden: http://graph.facebook.com/1240771104/picture -> https://fbcdn-profile-a.akamaihd.net/hprofile-ak-prn2/t...

我已经引用了this 问题,但我认为他只是在调用图像而不是使用创建块将其保存到数据库中。

这是我的用户模型...

def self.find_for_facebook_oauth(auth, signed_in_resource=nil)
    user = User.where(:provider => auth.provider, :uid => auth.uid).first
    if user
      return user
    else
      registered_user = User.where(:email => auth.info.email).first
      if registered_user
        return registered_user
      else
        user = User.create( 
                            name:auth.extra.raw_info.name,
                            provider:auth.provider,
                            uid:auth.uid,
                            email:auth.info.email,
                            image:auth.info.image,
                            password:Devise.friendly_token[0,20],
                          )
      end    
    end
end

我在“def.self_for_facebook”下方添加了一个 URI 助手,因为我认为我只需要将 http 获取到 https。所以我从另一个堆栈问题中收集到。

private

def process_uri(uri)
  require 'open-uri'
  require 'open_uri_redirections'
  open(uri, :allow_redirections => :safe) do |r|
  r.base_uri.to_s
  end
end

需要补充吗

if auth.info.image.present?
  image_url = process_uri(auth.info.image)
  user.update_attribute(:image, URI.parse(avatar_url))
end

到创建块? 这个:

        if auth.info.image.present?
            uri = URI.parse(auth.info.image)
            uri.scheme = 'https'
            user.update_attribute(:image, URI.parse(uri))
        end

        user = User.create( 
                            name:auth.extra.raw_info.name,
                            provider:auth.provider,
                            uid:auth.uid,
                            email:auth.info.email,
                            password:Devise.friendly_token[0,20],
                          )

      end    

让我...

bad URI(is not URI?): https://graph.facebook.com/1240771104/picture

但这是怎么回事。链接给我图片!!哇,伙计!我一定离得很近。

【问题讨论】:

    标签: ruby ruby-on-rails-4 paperclip


    【解决方案1】:

    在您的用户模型中

    #user.rb
    def self.find_for_facebook_oauth(auth, signed_in_resource=nil)
        user = User.create( image:process_uri(auth.info.image))
    end
    
    private
    
    def self.process_uri(uri)
      require 'open-uri'
      require 'open_uri_redirections'
      open(uri, :allow_redirections => :safe) do |r|
        r.base_uri.to_s
      end
    end
    

    或者如果您不想使用open uri redirections gem,则将process_uri 方法更改为

    def self.process_uri(uri)
       avatar_url = URI.parse(uri)
       avatar_url.scheme = 'https'
       avatar_url.to_s
    end
    

    【讨论】:

    • 它只适用于我的 open-uri,我还必须将我的 cookie 更改为活动记录,按照说明进行操作 here 非常感谢 @deep!
    【解决方案2】:

    这似乎是由 OpenURI.redirectable 引起的?方法。 它指定:

    def OpenURI.redirectable?(uri1, uri2) # :nodoc:
    # This test is intended to forbid a redirection from http://... to
    # file:///etc/passwd, file:///dev/zero, etc.  CVE-2011-1521
    # https to http redirect is also forbidden intentionally.
    # It avoids sending secure cookie or referer by non-secure HTTP protocol.
    # (RFC 2109 4.3.1, RFC 2965 3.3, RFC 2616 15.1.3)
    # However this is ad hoc.  It should be extensible/configurable.
    uri1.scheme.downcase == uri2.scheme.downcase ||
    (/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:http|ftp)\z/i =~ uri2.scheme)
    

    结束

    评论暗示(但没有明确说明)http --> https 重定向应该是可能的。

    我通过创建猴子补丁并覆盖此方法解决了这个问题,将最后一行更新为:

    (/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:http|ftp|https)\z/i =~ uri2.scheme)
    

    【讨论】: