36

我以前一直在使用token_authenticatable来保护我的 API,但是,我发现它已被弃用?我应该改用什么,为什么他们不推荐使用它?

4

5 回答 5

41

我想保持向后兼容性,所以我只是将所有内容都转移到一个关注点以避免警告。这是我的代码和相关规范:

/app/models/concerns/token_authenticable.rb

module TokenAuthenticatable
  extend ActiveSupport::Concern

  module ClassMethods
    def find_by_authentication_token(authentication_token = nil)
      if authentication_token
        where(authentication_token: authentication_token).first
      end
    end
  end

  def ensure_authentication_token
    if authentication_token.blank?
      self.authentication_token = generate_authentication_token
    end
  end

  def reset_authentication_token!
    self.authentication_token = generate_authentication_token
    save
  end

  private

  def generate_authentication_token
    loop do
      token = Devise.friendly_token
      break token unless self.class.unscoped.where(authentication_token: token).first
    end
  end
end

/app/models/user.rb

class User < ActiveRecord::Base
    include TokenAuthenticatable
end

/app/models/employee.rb

class Employee < ActiveRecord::Base
    include TokenAuthenticatable
end

/spec/models/user_spec.rb

describe User do
    it_behaves_like 'token_authenticatable'
end

/spec/models/employee_spec.rb

describe Employee do
    it_behaves_like 'token_authenticatable'
end

规范/shared_examples/token_authenticable.rb

shared_examples 'token_authenticatable' do
  describe '.find_by_authentication_token' do
    context 'valid token' do
      it 'finds correct user' do
        class_symbol = described_class.name.underscore
        item = create(class_symbol, :authentication_token)
        create(class_symbol, :authentication_token)

        item_found = described_class.find_by_authentication_token(
          item.authentication_token
        )

        expect(item_found).to eq item
      end
    end

    context 'nil token' do
      it 'returns nil' do
        class_symbol = described_class.name.underscore
        create(class_symbol)

        item_found = described_class.find_by_authentication_token(nil)

        expect(item_found).to be_nil
      end
    end
  end

  describe '#ensure_authentication_token' do
    it 'creates auth token' do
      class_symbol = described_class.name.underscore
      item = create(class_symbol, authentication_token: '')

      item.ensure_authentication_token

      expect(item.authentication_token).not_to be_blank
    end
  end

  describe '#reset_authentication_token!' do
    it 'resets auth token' do
    end
  end
end
于 2013-09-28T21:15:12.910 回答
31

从他们的博客

“我们无法消化 TokenAuthenticatable 提供的身份验证令牌,因为它们通常是 API 中多次使用该令牌的一部分。由于可身份验证令牌的使用在应用程序之间可能会有很大差异,每个应用程序都需要不同的安全保证,因此我们决定从 Devise 中删除 TokenAuthenticatable,允许用户选择最佳选项。”

现在由开发人员根据他们对身份验证令牌的使用情况选择最合适的。

签出这个要点

于 2013-09-21T13:56:17.337 回答
0

我之前已经回答了这个问题,并提供了一个替代示例代码,涵盖了如何使用 Rails 和 Warden 进行 OAuth 2.0 API/Token 身份验证

Devise 与 API 几乎无关,我总是感到不舒服,试图与 Devise 搏斗以使其按我需要的方式工作,所以我放弃了它,但是 Devise 所基于的 Warden 中间件对于支持多种身份验证策略仍然有用,并且是什么我的示例使用。

于 2014-05-28T10:53:19.093 回答
0

我一直在使用devise_token_auth gem,它是Devise wiki page for token authentication中列出的备选方案之一。

我不知道它现在是否是 Devise 令牌身份验证的事实标准,但它绝对是我的首选。

于 2015-10-21T12:28:27.597 回答
0

这看起来是一个非常古老的问题,但我会gem在这里记录一个很棒的问题。

您可以使用Doorkeeper Gem保护您的 API,这是一个很棒的 Rails 应用程序的 oauth 提供程序。

于 2016-05-13T17:39:27.523 回答