ruby-on-rails - Rails 4、Devise、Omniauth、Cancan、Twitter API

标签 ruby-on-rails ruby twitter devise omniauth

这可能很愚蠢,但我已经用谷歌搜索并经历了堆栈溢出,但在浪费了几个小时后没有找到任何运气。

基本上,我克隆并部署了这个 - https://github.com/alex-klepa/rails4-bootstrap-devise-cancan-omniauth并没有进行任何更改(除了输入我的消费者 key 和 secret )。

我能够使用我的 twitter 应用程序和 facebook 应用程序登录凭据启动并运行它。我遇到问题的地方是使用 twitter gem 和 fb_graph gem 以及omniauth 在身份模型中创建和存储的凭据属于 User 模型。

似乎已经有用户的 session 管理 - 为该用户生成的 token 和 secret 存储在身份模型中,但我仍然收到“您的凭据不允许访问此资源”。

长话短说,这是 Twitter 配置:

Twitter.configure do |config|
    config.consumer_key = 'yxxxxxx'
    config.consumer_secret = 'kxxxxxxx'
    config.oauth_token = ['need help here']
    config.oauth_token_secret = ['need help here']
end

我希望将一些动态内容放入 oauth_token 和 oauth_token_secret 字段中,这些字段取决于当前用户 session ,这样我就可以将 API 调用放入我的 View 中。

预先感谢您给我的任何帮助!

编辑:

我只是想到模型可能会有所帮助。 (其他所有内容都位于 git 链接中)*还有另外两个支持模型,auth_definitions.rb Roles.rb,它们支持 Devise,但似乎在这里没有任何影响。

user.rb
    class User
      include Mongoid::Document
      include Mongoid::Timestamps
      include User::AuthDefinitions
      include User::Roles

      has_many :identities


      field :email, type: String
      field :image, type: String
      field :first_name, type: String
      field :last_name, type: String
      field :roles_mask, type: Integer

      validates_presence_of :email, :first_name, :last_name

      def full_name
        "#{first_name} #{last_name}"
      end

    end

身份.rb

class Identity
  include Mongoid::Document
  include Mongoid::Timestamps

  belongs_to :user, index: true

  field :uid, type: String
  field :provider, type: String
  field :token, type: String
  field :secret, type: String
  field :expires_at, type: DateTime

  field :email, type: String
  field :image, type: String
  field :nickname, type: String
  field :first_name, type: String
  field :last_name, type: String

  index({ uid: 1, provider: 1 }, { unique: true })


  def self.from_omniauth(auth)
    identity = where(auth.slice(:provider, :uid)).first_or_create do |identity|
      identity.provider     = auth.provider
      identity.uid          = auth.uid
      identity.token        = auth.credentials.token
      identity.secret       = auth.credentials.secret if auth.credentials.secret
      identity.expires_at   = auth.credentials.expires_at if auth.credentials.expires_at
      identity.email        = auth.info.email if auth.info.email
      identity.image        = auth.info.image if auth.info.image
      identity.nickname     = auth.info.nickname
      identity.first_name   = auth.info.first_name
      identity.last_name    = auth.info.last_name
    end
    identity.save!

    if !identity.persisted?
      redirect_to root_url, alert: "Something went wrong, please try again."
    end
    identity
  end

  def find_or_create_user(current_user)
    if current_user && self.user == current_user
      # User logged in and the identity is associated with the current user
      return self.user
    elsif current_user && self.user != current_user
      # User logged in and the identity is not associated with the current user
      # so lets associate the identity and update missing info
      self.user = current_user
      self.user.email       ||= self.email
      self.user.image       ||= self.image
      self.user.first_name  ||= self.first_name
      self.user.last_name   ||= self.last_name
      self.user.skip_reconfirmation!
      self.user.save!
      self.save!
      return self.user
    elsif self.user.present?
      # User not logged in and we found the identity associated with user
      # so let's just log them in here
      return self.user
    else
      # No user associated with the identity so we need to create a new one
      self.build_user(
        email: self.email,
        image: self.image,
        first_name: self.first_name,
        last_name: self.last_name,
        roles: [AppConfig.default_role]
      )
      self.user.save!(validate: false)
      self.save!
      return self.user
    end
  end

  def create_user

  end
end

最佳答案

碰巧我几天前就按照你的要求做了。第一件事是在回调从 twitter 返回后将用户的 token 和 secret 存储在 session 哈希中,在我的例子中是:

omni_callbacks_controller.rb:

session[:token] = request.env["omniauth.auth"].credentials.token
session[:secret] = request.env["omniauth.auth"].credentials.secret

之后,您只需在 Twitter.config 中设置消费者凭据(另请编辑您的消费者的 token 和 secret !重要的是不要向全世界展示此信息):

Twitter.configure do |config|
    config.consumer_key = APP_TOKEN
    config.consumer_secret = APP_SECRET
end

那么您所要做的就是创建 Twitter.client,并在 session 哈希中传递用户的 token 和 secret 存储:

client = Twitter::Client.new(oauth_token: session[:token], oauth_token_secret: session[:secret])
client.update("This sends a message to user's feed on twitter")

关于ruby-on-rails - Rails 4、Devise、Omniauth、Cancan、Twitter API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18554619/

相关文章:

ruby-on-rails - 在 Ruby/(Rails 插件/Gem) 中恢复解析器

ruby - 将 Sinatra/Rack 应用程序制作成单个本地可执行文件有什么好处?

mysql - Ruby on Rails MYSQL 错误访问被拒绝用户 'root@localhost'

javascript - 如何在 Rails 应用程序中从 Javascript 写入 Heroku 的日志?

javascript - 为什么我的 JSON 数据作为数据属性从 erb 传递到 Javascript 时会丢失?

api - 什么是 Twitter 指数?

twitter - Tweepy 获取用户创建 Twitter 帐户的日期

ruby-on-rails - Rails 事件记录 : 'attribute_before_last_save' vs 'attribute_was'

ruby - Wicked wizard gem 忽略我的步骤并跳转到 request_steps/wicked_finish

twitter - 为什么不推特 :image work properly when posting link in Twitter?