设备 token_authenticatable 已弃用,有什么替代方法吗?

37

我以前使用过token_authenticatable来保护我的API,但是我发现它已被弃用了。那么我应该使用什么替代方案?为什么会被弃用?

5个回答

41

我希望保持向后兼容性,所以我将所有内容移动到关注点中以避免警告。这是我的代码和相关规范:

/app/models/concerns/token_authenticatable.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

spec/shared_examples/token_authenticatable.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

4
+1 - 不错,但我认为你应该在generate_authentication_token方法中将User替换为self.class.unscoped,以便Concern不会绑定到特定的User类。 - m_x
你能解释一下为什么我们需要执行 reset_authentication_token! 吗? - Arup Rakshit
即使在实施此操作后,您仍需要自己处理令牌(存储在数据库中、通过请求生成等)。 - Lucio
我认为值得研究devise_token_auth - Jason Swett

32

根据他们的博客

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

现在开发人员可以根据他们对身份验证令牌的使用来选择最合适的选项。

查看这个Gist


如果您需要特定库的建议,我一直很满意devise_token_auth - Jason Swett

0

0

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

对于API而言,Devise几乎不相关,我总是感到不舒服尝试与Devise搏斗,使其按照我所需的方式工作,因此我放弃了它,但基于Warden中间件的Devise仍然有用于支持多种身份验证策略,这也是我的示例所使用的。


0

这似乎是一个非常古老的问题,但我会在这里记录一个很棒的gem

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接