如何在设计中使用http身份验证,并使用可选的omniauth令牌作为身份验证令牌

Str*_*ine 7 facebook ruby-on-rails http-authentication devise omniauth

我们有一个rails应用程序设置,它使用devise&omniauth允许通过facebook身份验证登录.我们还有一个移动应用程序,当前使用http身份验证通过传递用户名和密码或传入http身份验证令牌来登录rails应用程序.到目前为止,这一切都很有效.

移动应用程序还具有与Facebook本身进行身份验证的能力,并直接在自己和Facebook之间接收用户facebook令牌.

我想弥合这个差距,以便如果用户通过Facebook从移动应用程序登录并拥有他们的facebook令牌,允许将facebook令牌用作rails app上的身份验证,就好像他们已经从facebook通过浏览器.

最终结果是移动应用程序可以通过以下方式登录用户:

1)用户名/密码或2)http认证令牌或3)omniauth(facebook)令牌

此外,在3)的情况下,如果用户尚未存在于rails应用程序中,则需要创建用户 - 现在已经使用浏览器端身份验证执行此操作,因此可能无需执行任何操作.

如何在设计构造中最好地实现这一目标?

小智 10

刚刚做到这一点,但从未见过端到端的解决方案.

这解决了第3点.1和2很容易通过设计和其他地方的文档来完成.

将FB身份验证添加到您的网络应用程序并不太难,指示在omithuth和omniauth-facebook的github上.

如果你想这样做,我相信以下是独立的,没有进行omniauth-facebook集成.这类似于其他方法.我的想法是尝试尽可能地使用设计模型.

你需要fb_graph gem.

在移动客户端上,您可以适当地使用FB进行身份验证,并将返回的访问令牌放在http请求的标头中.我使用了标头fb_access_token.就像基本身份验证一样,您需要通过SSL发送此信息以避免嗅探令牌.使用标题允许我在不更改请求的情况下交换基本auth和FB auth,但如果您愿意,可以使用参数.

该解决方案实现了一个基于可验证的可验证监管策略的监管策略.这里的不同之处在于,此策略使用名为fb_access_token的HTTP标头,其中包含使用移动应用程序检索的facebook访问标记字符串.

一旦你知道这一点,代码就非常简单了.

在文件的config/initializers目录中,添加以下内容.我碰巧叫我的fb_api_strategy.rb:

# authentication strategy to support API authentication over the webservice
# via facebook

require 'devise/strategies/database_authenticatable'
require 'fb_graph'
require 'warden'

module Devise
  module Strategies
    class FbMobileDatabaseAuthenticatable < Authenticatable
  def valid?
    # if we have headers with the facebook access key
    !!request.headers["fb_access_token"]
  end

  def authenticate!
    token = request.headers["fb_access_token"]
    fbuser = FbGraph::User.me(token)
    fbuser = fbuser.fetch

    user = User.find_for_facebook_mobile_client(fbuser.email)

    # this either creates a new user for the valid FB account, or attaches
    # this session to an existing user that has the same email as the FB account

    if !!user && validate(user) { true }
      user.after_database_authentication
      success!(user)
    elsif !halted? || !user
      fail(:invalid)
        end
      end
    end
  end
end

Warden::Strategies.add(:fb_database_authenticatable,
                       Devise::Strategies::FbMobileDatabaseAuthenticatable)
Run Code Online (Sandbox Code Playgroud)

在config/initializers中,将以下内容添加到devise.rb:

  config.warden do |manager|
    manager.default_strategies(:scope => :user).unshift :fb_database_authenticatable
  end
Run Code Online (Sandbox Code Playgroud)

要允许您根据FB电子邮件创建用户或查找现有用户,请将以下内容添加到您的用户模型:

  def self.find_for_facebook_mobile_client(fb_email)
    if user = User.where(:email => fb_email).first
      user
    else
      User.create!(:email => fb_email, :password => Devise.friendly_token[0,20])
    end
  end
Run Code Online (Sandbox Code Playgroud)

我不认为fb_database_authenticatable是一个准确的名字,但我会把它作为读者的练习.另一个练习是缓存/存储FB访问令牌,并且可能在每次调用时避免RT到FB.您应该注意,如果您在双方都进行FB身份验证,那么来自移动应用程序和rails应用程序的访问令牌会有所不同,我怀疑大多数人都希望这样做.这可能会影响您的缓存方案.

我认为这样做 - 快乐的编码.

  • 需要注意的事项:使用FB帐户的基本权限不提供电子邮件地址.您需要明确要求用户提供此权限. (2认同)