Ошибка при публикации в Twitter

Я пытался разрешить пользователю твитнуть из моего приложения rails с помощью gem omniauth-twitter и twitter-gem и следующего кода ниже, но каждый раз, когда я отправляю твит, я получаю следующую ошибку.

“Twitter::Error::Forbidden - Your credentials do not allow access to this resource:”

У меня настроен следующий код для Twitter.

user.rb

def tweet(tweet)
  client = Twitter::REST::Client.new do |config|
    config.consumer_key        = ENV["TWITTER_CONSUMER_KEY"]
    config.consumer_secret     = ENV["TWITTER_CONSUMER_SECRET"]
    config.access_token        = ENV["TWITTER_ACCESS_TOKEN"]
    config.access_token_secret = ENV["TWITTER_ACCESS_SECRET"]
  end

  client.update(tweet)
end

routes.rb

resources :tweets, only: [:new, :create]

Я ничего не менял в своем контроллере сессий, созданном с помощью devise.

class Devise::SessionsController < DeviseController
  prepend_before_filter :require_no_authentication, :only => [ :new, :create ]
  prepend_before_filter :allow_params_authentication!, :only => :create
  prepend_before_filter { request.env["devise.skip_timeout"] = true }

# GET /resource/sign_in
def new
 self.resource = resource_class.new(sign_in_params)
 clean_up_passwords(resource)
 respond_with(resource, serialize_options(resource))
 respond_to do |format|
  format.js
end   
end

# POST /resource/sign_in
def create
 self.resource = warden.authenticate!(auth_options)
 set_flash_message(:notice, :signed_in) if is_navigational_format?
 sign_in(resource_name, resource)
 respond_with resource, :location => after_sign_in_path_for(resource)
end

# DELETE /resource/sign_out
 def destroy
  redirect_path = after_sign_out_path_for(resource_name)
  signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
  set_flash_message :notice, :signed_out if signed_out && is_navigational_format?

 # We actually need to hardcode this as Rails default responder doesn't
 # support returning empty response on GET request
 respond_to do |format|
  format.all { head :no_content }
  format.any(*navigational_formats) { redirect_to redirect_path }
end
end

protected

def sign_in_params
 devise_parameter_sanitizer.sanitize(:sign_in)
end

def serialize_options(resource)
methods = resource_class.authentication_keys.dup
methods = methods.keys if methods.is_a?(Hash)
methods << :password if resource.respond_to?(:password)
{ :methods => methods, :only => [:password] }
end

def auth_options
  { :scope => resource_name, :recall => "#{controller_path}#new" }
end
end

tweets_controller.rb

class TweetsController < ApplicationController

  def new
  end

  def create
   current_user.tweet(twitter_params[:message])
   redirect_to root_path
  end

  def twitter_params
   params.require(:tweet).permit(:message)
  end

  end

На мой взгляд, я создал форму для заполнения пользователем и кнопку для отправки твита.

 <p>
  <%= form_for :tweet, url: tweets_path, method: :post do |f| %>
    <%= f.text_field :message %>
    <%= f.submit "Send Tweet" %>
  <% end %>
 </p>

ОБНОВЛЕНИЕ: вот мой журнал сервера

    "Started POST "/tweets" for 127.0.0.1 at 2014-04-29 11:26:48 -0500
    Processing by TweetsController#create as HTML
    Parameters: {"utf8"=>"✓",      "authenticity_token"=>"wRGfnEqErGE3enZ2m5/cjBK5N8Ai+z/TprqI5jmsbJY=", "tweet"=>  {"message"=>"Testing Tweet!"}, "commit"=>"Send Tweet"}
    User Load (1.0ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY   "users"."id" ASC LIMIT 1
    Completed 500 Internal Server Error in 793ms

Twitter::Error::Forbidden - Your credentials do not allow access to this resource:
  twitter (5.1.1) lib/twitter/rest/response/raise_error.rb:22:in `on_complete'
  faraday (0.8.8) lib/faraday/response.rb:9:in `block in call'
  faraday (0.8.8) lib/faraday/response.rb:63:in `on_complete'
  faraday (0.8.8) lib/faraday/response.rb:8:in `call'
  faraday (0.8.8) lib/faraday/request/url_encoded.rb:14:in `call'
  faraday (0.8.8) lib/faraday/request/multipart.rb:13:in `call'
  twitter (5.1.1) lib/twitter/rest/request/multipart_with_file.rb:15:in `call'
  faraday (0.8.8) lib/faraday/connection.rb:253:in `run_request'
  faraday (0.8.8) lib/faraday/connection.rb:118:in `post'
  twitter (5.1.1) lib/twitter/rest/client.rb:131:in `request'
  twitter (5.1.1) lib/twitter/rest/client.rb:103:in `post'
  twitter (5.1.1) lib/twitter/rest/api/utils.rb:123:in `object_from_response'
  twitter (5.1.1) lib/twitter/rest/api/tweets.rb:125:in `update'
  app/models/user.rb:93:in `tweet'
  app/controllers/tweets_controller.rb:7:in `create'
  actionpack (4.0.2) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
  actionpack (4.0.2) lib/abstract_controller/base.rb:189:in `process_action'
  actionpack (4.0.2) lib/action_controller/metal/rendering.rb:10:in `process_action'
  actionpack (4.0.2) lib/abstract_controller/callbacks.rb:18:in `block in process_action'
  activesupport (4.0.2) lib/active_support/callbacks.rb:403:in `_run__4448031954415073372__process_action__callbacks'
  activesupport (4.0.2) lib/active_support/callbacks.rb:80:in `run_callbacks'
  actionpack (4.0.2) lib/abstract_controller/callbacks.rb:17:in `process_action'
  actionpack (4.0.2) lib/action_controller/metal/rescue.rb:29:in `process_action'
  actionpack (4.0.2) lib/action_controller/metal/instrumentation.rb:31:in `block in process_action'
  activesupport (4.0.2) lib/active_support/notifications.rb:159:in `block in instrument'
  activesupport (4.0.2) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
  activesupport (4.0.2) lib/active_support/notifications.rb:159:in `instrument'
  actionpack (4.0.2) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
  actionpack (4.0.2) lib/action_controller/metal/params_wrapper.rb:245:in `process_action'
  activerecord (4.0.2) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
  actionpack (4.0.2) lib/abstract_controller/base.rb:136:in `process'
  actionpack (4.0.2) lib/abstract_controller/rendering.rb:44:in `process'
  session_off (0.5.0) lib/session_off.rb:176:in `process_with_session_off'
  actionpack (4.0.2) lib/action_controller/metal.rb:195:in `dispatch'
  actionpack (4.0.2) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
  actionpack (4.0.2) lib/action_controller/metal.rb:231:in `block in action'
  actionpack (4.0.2) lib/action_dispatch/routing/route_set.rb:80:in `call'
  actionpack (4.0.2) lib/action_dispatch/routing/route_set.rb:80:in `dispatch'
  actionpack (4.0.2) lib/action_dispatch/routing/route_set.rb:48:in `call'
  actionpack (4.0.2) lib/action_dispatch/journey/router.rb:71:in `block in call'
  actionpack (4.0.2) lib/action_dispatch/journey/router.rb:59:in `each'
  actionpack (4.0.2) lib/action_dispatch/journey/router.rb:59:in `call'
  actionpack (4.0.2) lib/action_dispatch/routing/route_set.rb:680:in `call'
  omniauth (1.1.4) lib/omniauth/strategy.rb:184:in `call!'
  omniauth (1.1.4) lib/omniauth/strategy.rb:164:in `call'
  omniauth (1.1.4) lib/omniauth/strategy.rb:184:in `call!'
  omniauth (1.1.4) lib/omniauth/strategy.rb:164:in `call'
  rack-livereload (0.3.15) lib/rack/livereload.rb:23:in `_call'
  rack-livereload (0.3.15) lib/rack/livereload.rb:14:in `call'
  warden (1.2.3) lib/warden/manager.rb:35:in `block in call'
  warden (1.2.3) lib/warden/manager.rb:34:in `catch'
  warden (1.2.3) lib/warden/manager.rb:34:in `call'
  rack (1.5.2) lib/rack/etag.rb:23:in `call'
  rack (1.5.2) lib/rack/conditionalget.rb:35:in `call'
  rack (1.5.2) lib/rack/head.rb:11:in `call'
  actionpack (4.0.2) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
  actionpack (4.0.2) lib/action_dispatch/middleware/flash.rb:241:in `call'
  rack (1.5.2) lib/rack/session/abstract/id.rb:225:in `context'
  rack (1.5.2) lib/rack/session/abstract/id.rb:220:in `call'
  actionpack (4.0.2) lib/action_dispatch/middleware/cookies.rb:486:in `call'
  activerecord (4.0.2) lib/active_record/query_cache.rb:36:in `call'
  activerecord (4.0.2) lib/active_record/connection_adapters/abstract/connection_pool.rb:626:in `call'
  activerecord (4.0.2) lib/active_record/migration.rb:369:in `call'
  actionpack (4.0.2) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
  activesupport (4.0.2) lib/active_support/callbacks.rb:373:in `_run__810443810394189641__call__callbacks'
  activesupport (4.0.2) lib/active_support/callbacks.rb:80:in `run_callbacks'
  actionpack (4.0.2) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
  actionpack (4.0.2) lib/action_dispatch/middleware/reloader.rb:64:in `call'
  actionpack (4.0.2) lib/action_dispatch/middleware/remote_ip.rb:76:in `call'
  better_errors (1.1.0) lib/better_errors/middleware.rb:84:in `protected_app_call'
  better_errors (1.1.0) lib/better_errors/middleware.rb:79:in `better_errors_call'
  better_errors (1.1.0) lib/better_errors/middleware.rb:56:in `call'
  airbrake (3.1.15) lib/airbrake/rails/middleware.rb:13:in `call'
  actionpack (4.0.2) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
  actionpack (4.0.2) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  railties (4.0.2) lib/rails/rack/logger.rb:38:in `call_app'
  railties (4.0.2) lib/rails/rack/logger.rb:20:in `block in call'
  activesupport (4.0.2) lib/active_support/tagged_logging.rb:67:in `block in tagged'
  activesupport (4.0.2) lib/active_support/tagged_logging.rb:25:in `tagged'
  activesupport (4.0.2) lib/active_support/tagged_logging.rb:67:in `tagged'
  railties (4.0.2) lib/rails/rack/logger.rb:20:in `call'
  quiet_assets (1.0.2) lib/quiet_assets.rb:18:in `call_with_quiet_assets'
  actionpack (4.0.2) lib/action_dispatch/middleware/request_id.rb:21:in `call'
  rack (1.5.2) lib/rack/methodoverride.rb:21:in `call'
  rack (1.5.2) lib/rack/runtime.rb:17:in `call'
  activesupport (4.0.2) lib/active_support/cache/strategy/local_cache.rb:83:in `call'
  rack (1.5.2) lib/rack/lock.rb:17:in `call'
  actionpack (4.0.2) lib/action_dispatch/middleware/static.rb:64:in `call'
  rack (1.5.2) lib/rack/sendfile.rb:112:in `call'
  airbrake (3.1.15) lib/airbrake/user_informer.rb:16:in `_call'
  airbrake (3.1.15) lib/airbrake/user_informer.rb:12:in `call'
  railties (4.0.2) lib/rails/engine.rb:511:in `call'
  railties (4.0.2) lib/rails/application.rb:97:in `call'
  rack (1.5.2) lib/rack/lock.rb:17:in `call'
  rack (1.5.2) lib/rack/content_length.rb:14:in `call'
  rack (1.5.2) lib/rack/handler/webrick.rb:60:in `service'
  /opt/boxen/rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/webrick/httpserver.rb:138:in `service'
  /opt/boxen/rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/webrick/httpserver.rb:94:in `run'
  /opt/boxen/rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/webrick/server.rb:295:in `block in start_thread'



Started POST "/__better_errors/70276081720140/variables" for 127.0.0.1 at 2014-04-29 11:26:49 -0500"

person milehighcoder    schedule 29.04.2014    source источник
comment
Вы уверены, что ваши конфигурации на dev.twitter.com настроены для публикации, а не только для чтения?   -  person user3490997    schedule 29.04.2014
comment
Можете ли вы поделиться журналом сервера, созданным, когда вы нажимаете кнопку для отправки твита.   -  person Kirti Thorat    schedule 29.04.2014
comment
@ user3490997 да, они настроены на чтение и запись   -  person milehighcoder    schedule 29.04.2014
comment
@KirtiThorat Да, я обновился   -  person milehighcoder    schedule 29.04.2014
comment
Как вы устанавливаете переменные среды? Вы используете figaro драгоценный камень или он находится в .env файле?   -  person Kirti Thorat    schedule 29.04.2014
comment
фигаро и все в application.yml   -  person milehighcoder    schedule 29.04.2014
comment
Можете ли вы переключить ваши строки ENV на ENV.fetch("TWITTER_CONSUMER_KEY") и т. Д.? Это вызовет ошибку, если значения конфигурации отсутствуют, вместо того, чтобы просто дать вам nil   -  person akatakritos    schedule 29.04.2014
comment
@akatakritos Я сделал это, но теперь получаю следующую ошибку: неправильное количество аргументов (0 для 1..2)   -  person milehighcoder    schedule 29.04.2014


Ответы (1)


Думаю, вы пропустили конфиг для:

config.consumer_key        = ENV["TWITTER_CONSUMER_KEY"]
config.consumer_secret     = ENV["TWITTER_CONSUMER_SECRET"]
config.access_token        = ENV["TWITTER_ACCESS_TOKEN"]
config.access_token_secret = ENV["TWITTER_ACCESS_SECRET"]

Если переменные окружения не заданы, вы получите «неавторизованную» ошибку.

Просто для целей тестирования попробуйте фактически ввести свои данные вместо переменных ENV ... Это работает, это означает, что вы неправильно доставили файл yml.

person Hamdan    schedule 29.04.2014
comment
БОЛЬШОЕ СПАСИБО! Не знаю, почему я вообще не попробовал это. Извините за мое незнание, но я, очевидно, не хочу, чтобы эти коды были видны публике, как мне правильно доставить мой yml - person milehighcoder; 29.04.2014
comment
Попробуйте найти документацию по файлам yml. Или попробуйте установить эти переменные ENV в вашем файле initializer.rb. Дело в том, что вы неправильно устанавливаете эти переменные среды, поэтому вы получаете сообщение об ошибке, потому что они пусты. Просто установите их правильно (я рекомендую файл yml, который может игнорироваться git и не публиковаться), и все будет работать нормально. - person Hamdan; 29.04.2014
comment
конечно @hamdan. Я отметил ответ, я просто запутался, почему мой yml файл их не забирает. Спасибо хоть! - person milehighcoder; 29.04.2014
comment
Это тоже зависит от вашего сервера ... например, для heroku вы можете использовать figaro gem. - person Hamdan; 29.04.2014
comment
все работает, и я принял ответ. Прежде чем размещать еще один вопрос, хотел спросить, как это изменить для каждого пользователя. Прямо сейчас, если другой пользователь входит в систему через твиттер и отправляет сообщение, это происходит из моей учетной записи. Я попытался изменить config.access_token и secret на = self.oauth_token и self.oauth.secret соответственно - person milehighcoder; 29.04.2014
comment
Если пользователь входит в систему через твиттер, oauth наверняка получит свои ключи. Проверьте документацию oauth, чтобы использовать эти значения по своему усмотрению, но я не знаю, действительно ли разрешено публиковать сообщения от имени пользователя. - person Hamdan; 29.04.2014