Gem [已解决] 使用 CarrierWave-Upyun 上传图片时发生 RestClient::Unauthorized (401 Unauthorized) 错误

angryz · 2014年05月10日 · 最后由 angryz 回复于 2014年05月13日 · 5300 次阅读

2014.05.13 更新 该问题纯属自己粗心,犯了“下意识认为这部分没有问题”的错误,再次证明“你以为的并不一定就是你以为的那样”。 自己发现的结果在 #6 楼。惭愧!

——————————————————

运行环境

  • ruby 1.9.3
  • rails 4.1.0
  • carrierwave 0.10.0
  • carrierwave-upyun 0.1.6
  • rest-client 1.6.7

又拍云

  • 外链功能:开启
  • 表单功能:未开启
  • HTTPS 功能:未开启

操作员授权,以及 config/initializers/carrierwave.rb 配置都没有问题。

问题说明

  • 之前使用 Rails 3.2.0 版本时图片上传正常
  • 升级到 Rails 4.1.0 后修改 models 和 controllers 代码以遵循新特性,然后就出现了该错误
  • 该 Rails 应用主要是作为 Mobile App 的后端服务,由 App 通过 REST + JSON 方式调用
  • Mobile App 将图片以 Base64 编码作为 JSON 的一个参数发送到 Rails 应用,Rails 里面解码后通过 carrierwave-upyun 进行上传,代码片段如下: ```ruby class Auth < ActiveRecord::Base belongs_to :user has_secure_password attr_accessor :uploader_secure_token mount_uploader :avatar, ImageUploader

def image_data=(image_base64) unless image_base64.blank? data = StringIO.new(Base64.decode64(image_base64)) data.class.class_eval { attr_accessor :original_filename, :content_type } data.original_filename = self.email + '.jpg' data.content_type = 'image/jpg' self.avatar = data end end end


ImageUploader 是参考 @huacnlee 的 《[在 Rails 项目里面使用又拍云用于存储上传图片](http://huacnlee.com/blog/rails-app-image-store-with-carrierwave-upyun/#use-carrierwave)》 写的。

另外参考了帖子 《[关于又拍云的使用,undefined method 'uploader_secure_token'](http://ruby-china.org/topics/7132)》 也没有找到解决办法。

### 错误日志片段

D, [2014-05-10T14:47:28.897501 #67546] DEBUG -- : (BaseUploader.filename) bd3fdea8563a401c8b0accd61dd23a31 E, [2014-05-10T14:47:28.898015 #67546] ERROR -- : Binary data inserted for string type on column password_digest D, [2014-05-10T14:47:28.898240 #67546] DEBUG -- : SQL (0.1ms) INSERT INTO "auths" ("avatar", "created_at", "nickname", "password_digest", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?, ?) [["avatar", "bd3fdea8563a401c8b0accd61dd23a31.jpg"], ["created_at", "2014-05-10 06:47:28.897638"], ["nickname", "foobar1"], ["password_digest", "$2a$10$/NJLntYAY2pZiZ.06zkTPusCZa5g0vcRKPm93BmEBCGv9XIX1FAwO"], ["updated_at", "2014-05-10 06:47:28.897638"], ["user_id", 33]] D, [2014-05-10T14:47:28.898455 #67546] DEBUG -- : (BaseUploader.filename) bd3fdea8563a401c8b0accd61dd23a31 D, [2014-05-10T14:47:30.463842 #67546] DEBUG -- : (6.4ms) rollback transaction I, [2014-05-10T14:47:30.464289 #67546] INFO -- : Completed 500 Internal Server Error in 1645ms F, [2014-05-10T14:47:30.466549 #67546] FATAL -- : RestClient::Unauthorized (401 Unauthorized): app/controllers/users_controller.rb:47:in `create'


__这个问题我Google了半天,在stackoverflow上看了好几个相关的问题,都没有找到解决办法,烦请各位帮忙看看,谢谢!__
401 Unauthorized

访问未授权

出现该错误的可能有:

操作员或密码错误
空间名错误
其他错误(可从接口返回的 BODY 中获取详细信息)

upyun 401,看看 restclient 发出的 request 和 response

2 楼 已删除

#1 楼 @saiga 感谢回复!

正如我前面描述的,操作员和密码,以及空间名,都是可以确认没有错误的,而且在升级到 Rails 4.1.0 之前都是正常工作的。

而 carrierwave-upyun 并不会打印 restclient 的相关日志,所以也看不到 upyun 返回的的详细信息。由于接触 Ruby on Rails 刚开始没多久,我现在能想到的办法就是通过网络抓包来看看,如果有其他更好的办法请指点一下我。谢谢!

Completed 500 Internal Server Error in 1645ms
RestClient::Unauthorized (401 Unauthorized):

虽然没用过,不过日志显示这两个那应该是网络错误没跑了。 这个 gem 把返回的 resp 忽略 了,我用的是 rubymine,可以直接跳进 gem 源码里设断点,你可以试试模仿 store! 方法手动提交看看

carrierwave.rb

发来看看

#4 楼 @saiga 谢谢!我去了解一下你说的方法。

#5 楼 @huacnlee 十分感谢,我的问题已经解决了,其实原因很愚蠢。由于我是把 upyun 的配置放在 ENV 变量里的: carrierwave.rb

CarrierWave.configure do |config|
  config.storage = :upyun
  config.upyun_username = ENV['UPYUN_USER']
  config.upyun_password = ENV['UPYUN_PASS']
  config.upyun_bucket = ENV['UPYUN_BUCKET']
  config.upyun_bucket_domain = ENV['UPYUN_DOMAIN']
end

而 EVN 变量的配置我并没有直接配置在 shell 的环境变量中,而是配置在自定义文件 local_env.yml 中,然后在 application.rb 中将该文件的配置放入 ENV 里。 因为之前 upyun 上传都能正常工作,所以我下意识认为这部分都是没有问题的,但是经过仔细检查之后,发现这中间确实出了问题,而且是很低级的错误,不知道是什么时候引入的。

十分惭愧,自己没有仔细检查就来寻求帮助,看来遇到问题不能相信“下意识”,还是要一个个环节检查过去才行。总之再次感谢两位!

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