如何使用可选的 omniauth 令牌作为身份验证令牌在设计中使用 http 身份验证 [英] How to use http authentication in devise with an optional omniauth token as the authentication token

查看:36
本文介绍了如何使用可选的 omniauth 令牌作为身份验证令牌在设计中使用 http 身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We have a rails app setup that uses devise & omniauth to allow logging in via facebook authentication. We also have a mobile app that is currently using http authentication to login to the rails app either by passing username & password or by passing in the http authentication token. This all works great so far.

移动应用程序还能够通过 facebook 本身进行身份验证,并直接在其与 facebook 之间接收用户 facebook 令牌.

The mobile app also has the ability to authenticate with facebook itself and receive the user facebook token directly between itself and facebook.

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

I would like to bridge this gap so that if the user has logged in from the mobile app via facebook and has their facebook token, allow that facebook token to be used as the authentication on the rails app as if they had received it from facebook via the browser.

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

The end result would be that the mobile app can log a user in via:

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

1) username/password or 2) http authentication token or 3) omniauth (facebook) token

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

Also, in the case of 3), if the user doesn't yet exist on the rails app, would need to create the user - doing that now already with browser side authentication so there may be nothing more to do.

我如何才能在设计结构中最好地完成此任务?

How can I best accomplish this within the devise construct?

推荐答案

刚做了这个,但从未看到端到端的解决方案.

Just did this, but never saw an end-to-end solution.

这解决了第 3 点.1 &2 可以通过设计轻松实现并在其他地方记录.

This addresses point 3. 1 & 2 are easily accomplished with devise and documented elsewhere.

将 FB 身份验证添加到您的网络应用程序并不难,有关 omniauth 和 omniauth-facebook 的说明在 github 上.

Not too hard to add FB auth to your web app, the instructions are on github for omniauth and omniauth-facebook.

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

I believe the following stands alone, without doing the omniauth-facebook integration, if you want to do it that way. This is similar to other approaches out there. My idea was to attempt to use the devise model as closely as I could.

你需要 fb_graph gem.

You'll need the fb_graph gem.

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

On the mobile client, you authenticate with FB appropriately and put the returned access token in the header of your http requests. I used the header fb_access_token. Just like basic auth, you'll want to send this over SSL to avoid sniffing of the token. Using the header allows me to interchange basic auth and FB auth without changing the requests, but you could use a parameter if you prefer.

该解决方案实现了一种基于设计可验证监狱长策略的监狱长策略.此处的不同之处在于,该策略使用名为 fb_access_token 的 HTTP 标头,其中包含使用移动应用程序检索到的 facebook 访问令牌字符串.

This solution implements a warden strategy which is based off of the devise Authenticatable warden strategy. The difference here is the fact that this strategy utilizes an HTTP header called fb_access_token containing the facebook access token string that was retrieved using the mobile application.

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

Once you know this, the code is pretty straightforward.

在一个文件中,在 config/initializers 目录中,添加以下内容.我碰巧给我的 fb_api_strategy.rb 打电话:

In a file, in the config/initializers directory, add the following. I happened to call mine 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)

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

In config/initializers, add the following to devise.rb:

  config.warden do |manager|
    manager.default_strategies(:scope => :user).unshift :fb_database_authenticatable
  end

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

To allow you to either create a user or find an existing user based on the FB email, add the following to your user model:

  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

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

I don't think fb_database_authenticatable is an accurate name, but I'll leave that as an exercise for the reader. Another exercise is caching/storing the FB access token, and perhaps avoiding the RT to FB with each call. You should note that the access token from the the mobile app and the rails app will be different if you do FB authentication on both sides, which I suspect most people will want to do. This probably impacts your caching scheme.

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

I think that does it - happy coding.

这篇关于如何使用可选的 omniauth 令牌作为身份验证令牌在设计中使用 http 身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆