简体   繁体   English

如何在Devise,Angular和Mongoid中使用devise_token_auth

[英]How to use devise_token_auth with Devise, Angular and Mongoid

I'm trying to use Mongoid, devise, devise_token_auth and ng-token-auth for an token based authorisation for an API written in Rails with Mongoid and Angular as the client. 我正在尝试使用Mongoid,devise,devise_token_auth和ng-token-auth进行基于令牌的授权,该授权用于使用Mongoid和Angular作为客户端在Rails中编写的API。

The problem is when I follow the steps to install devise_token_auth I get an error when I restart my Rails app: undefined method table_exists?' 问题是,当我按照安装devise_token_auth的步骤操作时,当我重新启动Rails应用程序时出现错误: undefined method table_exists?' for User:Class` 对于用户:Class`

I'm assuming that because I'm using Mongoid the User class don't have the table_exists? 我假设因为我使用的是Mongoid, User类没有table_exists? method. 方法。

How can I get around this? 我怎么能绕过这个? Or, more importantly how can I get this to work? 或者,更重要的是我如何让它工作?

EDIT: Here's my User class 编辑:这是我的用户类

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

EDIT 2: Adding stack trace 编辑2:添加堆栈跟踪

http://pastebin.com/yMcr9mZ4 http://pastebin.com/yMcr9mZ4

Without seeing errors or source code, my guess is that your User class looks something like: 没有看到错误或源代码,我的猜测是你的User类看起来像:

class User
  include Mongoid::Document

  # Maybe some devise options here
end

Methods like table_exists? table_exists?这样的方法table_exists? and columns_hash are used by devise-token-auth because it's assumed that your user models inherit from ActiveRecord . columns_hash devise-token-auth使用和columns_hash ,因为假设您的用户模型继承自ActiveRecord See, for example, lines 87-94 of devise_token_auth/app/models/devise_token_auth/concerns/user.rb : 例如,请参阅devise_token_auth/app/models/devise_token_auth/concerns/user.rb

  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

One solution is to monkey patch your way to victory. 一个解决方案就是通过自己的方式获得胜利。 And/or you can implement those missing methods on your User class: 和/或您可以在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

Having used devise-token-auth without ActiveRecord myself, I can tell you it's possible. 我自己使用了没有ActiveRecord devise-token-auth ,我可以告诉你它是可能的。 Rather than do routes with mount_devise_token_auth_for , I implemented my own controllers that used the same underlying functions. 我没有使用mount_devise_token_auth_for做路由,而是使用了相同的底层函数实现了自己的控制器。 Look at the controllers in devise-token-auth and you'll see that you can follow the same flow, while replacing ActiveRecord methods with Mongoid methods. 查看Mongoid devise-token-auth中的控制器,您将看到可以遵循相同的流程,同时使用Mongoid方法替换ActiveRecord方法。 Good luck. 祝好运。

include this in your gemfile 将它包含在您的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'

run bundle install and follow the master branch configuration. 运行bundle install并遵循master分支配置。 it works for me. 这个对我有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM