【问题标题】:How to use devise_token_auth with Devise, Angular and Mongoid如何将 devise_token_auth 与 Devise、Angular 和 Mongoid 一起使用
【发布时间】:2015-08-04 06:41:48
【问题描述】:

我正在尝试使用 Mongoid、devise、devise_token_auth 和 ng-token-auth 为使用 Mongoid 和 Angular 作为客户端的 Rails 编写的 API 进行基于令牌的授权。

问题是当我按照步骤安装devise_token_auth 时,我在重新启动我的Rails 应用程序时收到错误:undefined methodtable_exists?'对于用户:类`

我假设因为我使用的是 Mongoid,所以 User 类没有 table_exists? 方法。

我该如何解决这个问题?或者,更重要的是,我怎样才能让它发挥作用?

编辑:这是我的用户类

class User

  include Mongoid::Document
  include Mongoid::Timestamps
  include Mongoid::Enum

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  ## Database authenticatable
  field :email,              type: String, default: ""
  field :encrypted_password, type: String, default: ""

  ## Recoverable
  field :reset_password_token,   type: String
  field :reset_password_sent_at, type: Time

  ## Rememberable
  field :remember_created_at, type: Time

  ## Trackable
  field :sign_in_count,      type: Integer, default: 0
  field :current_sign_in_at, type: Time
  field :last_sign_in_at,    type: Time
  field :current_sign_in_ip, type: String
  field :last_sign_in_ip,    type: String

  ## Confirmable
  field :confirmation_token,   type: String
  field :confirmed_at,         type: Time
  field :confirmation_sent_at, type: Time
  field :unconfirmed_email,    type: String # Only if using reconfirmable

  include DeviseTokenAuth::Concerns::User

  attr_accessor :reset_token

  enum :role, [:admin, :author]

  after_initialize :set_default_role, :if => :new_record?
  before_create :set_auth_token

  field :first_name,                                        type: String
  field :last_name,                                         type: String
  field :domain,                                                type: String
  field :payment_details,                               type: Hash
  field :subscriber,                                        type: Boolean
  field :stripe_details,                                type: Hash
  field :theme,                                                 type: String

  # Validation
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(?:\.[a-z\d\-]+)*\.[a-z]+\z/i
    before_save { self.email = email.downcase }
    before_create :create_remember_token


  # Get rid of devise-token_auth issues from activerecord
  def table_exists?
    true
  end

  def columns_hash
    # Just fake it for devise-token-auth; since this model is schema-less, this method is not really useful otherwise
    {} # An empty hash, so tokens_has_json_column_type will return false, which is probably what you want for Monogoid/BSON
  end

  def set_default_role
      self.role ||= :admin
  end

end

编辑 2:添加堆栈跟踪

http://pastebin.com/yMcr9mZ4

【问题讨论】:

  • 在你的 gemfile 中包含这个 ``` gem 'rails', '~> 5.1.4' gem 'mongoid', '~> 6.2', '>= 6.2.1' gem 'devise_token_auth' , git: 'github.com/BunHouth/devise_token_auth.git', branch: 'mongoid' gem 'mongoid-locker', '~> 0.3.4' ``` 运行 bundle install 并遵循 master 分支配置。它对我有用。

标签: ruby-on-rails angularjs devise


【解决方案1】:

没有看到错误或源代码,我猜你的 User 类看起来像:

class User
  include Mongoid::Document

  # Maybe some devise options here
end

table_exists?columns_hash 等方法被 devise-token-auth 使用,因为它假定您的用户模型继承自 ActiveRecord。例如,参见devise_token_auth/app/models/devise_token_auth/concerns/user.rb 的第 87-94 行:

  module ClassMethods
    protected


    def tokens_has_json_column_type?
      table_exists? && self.columns_hash['tokens'] && self.columns_hash['tokens'].type.in?([:json, :jsonb])
    end
  end

一种解决方案是用猴子补丁来取得胜利。和/或您可以在 User 类上实现那些缺少的方法:

class User
  # Get rid of devise-token_auth issues from activerecord
  def self.table_exists?
    true
  end

  def self.columns_hash
    # Just fake it for devise-token-auth; since this model is schema-less, this method is not really useful otherwise
    {} # An empty hash, so tokens_has_json_column_type will return false, which is probably what you want for Monogoid/BSON
  end

  def self.serialize(*args)

  end

  include DeviseTokenAuth::Concerns::User


  include Mongoid::Document
  include Mongoid::Timestamps
  include Mongoid::Enum

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  ## Database authenticatable
  field :email,              type: String, default: ""
  field :encrypted_password, type: String, default: ""

  ## Recoverable
  field :reset_password_token,   type: String
  field :reset_password_sent_at, type: Time

  ## Rememberable
  field :remember_created_at, type: Time

  ## Trackable
  field :sign_in_count,      type: Integer, default: 0
  field :current_sign_in_at, type: Time
  field :last_sign_in_at,    type: Time
  field :current_sign_in_ip, type: String
  field :last_sign_in_ip,    type: String

  ## Confirmable
  field :confirmation_token,   type: String
  field :confirmed_at,         type: Time
  field :confirmation_sent_at, type: Time
  field :unconfirmed_email,    type: String # Only if using reconfirmable



  attr_accessor :reset_token

  enum :role, [:admin, :author]

  after_initialize :set_default_role, :if => :new_record?
  before_create :set_auth_token

  field :first_name,                                        type: String
  field :last_name,                                         type: String
  field :domain,                                                type: String
  field :payment_details,                               type: Hash
  field :subscriber,                                        type: Boolean
  field :stripe_details,                                type: Hash
  field :theme,                                                 type: String

  # Validation
  valid_email_regex = /\A[\w+\-.]+@[a-z\d\-]+(?:\.[a-z\d\-]+)*\.[a-z]+\z/i
  before_save { self.email = email.downcase }
  before_create :create_remember_token




  def set_default_role
      self.role ||= :admin
  end



end

我自己使用了devise-token-auth 而没有ActiveRecord,我可以告诉你这是可能的。我没有使用mount_devise_token_auth_for 进行路由,而是实现了我自己的使用相同底层功能的控制器。查看devise-token-auth 中的控制器,您会发现您可以遵循相同的流程,同时将ActiveRecord 方法替换为Mongoid 方法。祝你好运。

【讨论】:

  • 谢谢!隧道尽头似乎有光 :) 我已经按照您的解释添加了该方法,但仍然出现错误。我正在用我的User 类更新我的答案
  • 知道会发生什么吗?再次感谢您的帮助
  • 我根据你的例子更新了我的例子。在包含 devise_token_auth 关注点之前,您需要创建方法,所以我重新订购了它们。我对 Mongoid 了解不多,但假设它可以序列化一个数组(在这种情况下为tokens),那么覆盖serialize 方法应该没问题。最后,你的正则表达式是动态常量赋值会导致错误,所以我把它改成了小写。
  • devise_token_auth 使用我们在此处创建的所有 3 个方法来确定是否需要将令牌数组序列化为 SQL 数据库中的 JSON。您需要验证令牌反序列化/序列化是否仍按 gem 的预期工作。
  • 我已经接受了答案,但老实说,我放弃了编写自己的身份验证和角度库。
【解决方案2】:

将其包含在您的 gemfile 中

gem 'rails',                      '~> 5.1.4'
gem 'mongoid',                    '~> 6.2', '>= 6.2.1'
gem 'devise_token_auth',          git: 'https://github.com/BunHouth/devise_token_auth.git', branch: 'mongoid'
gem 'mongoid-locker', '~> 0.3.4'

运行bundle install 并遵循master 分支配置。它对我有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-18
    • 2013-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多