Только что сделал это, но никогда не видел комплексного решения.
Это относится к пункту 3. 1 и 2 легко осуществляются с помощью устройства и документированы в другом месте.
Не так сложно добавить FB auth в ваше веб-приложение, инструкции на github для omniauth и omniauth-facebook.
Я полагаю, что следующее стоит без интеграции с omniauth-facebook, если вы хотите сделать это таким образом. Это похоже на другие подходы там. Моя идея состояла в том, чтобы попытаться использовать разработанную модель как можно точнее.
Вам понадобится камень fb_graph.
На мобильном клиенте вы соответствующим образом аутентифицируетесь с помощью FB и помещаете возвращенный токен доступа в заголовок ваших http-запросов. Я использовал заголовок fb_access_token. Так же, как обычная аутентификация, вы захотите отправить ее через SSL, чтобы избежать перехвата токена. Использование заголовка позволяет мне обмениваться базовой аутентификацией и аутентификацией FB без изменения запросов, но вы можете использовать параметр если вы предпочитаете.
Это решение реализует стратегию надзирателя, основанную на разработанной стратегии поддающегося проверке надзирателя. Разница здесь в том, что в этой стратегии используется HTTP-заголовок fb_access_token, содержащий строку токена доступа к 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)
В config / initializer добавьте следующее в devise.rb:
config.warden do |manager|
manager.default_strategies(:scope => :user).unshift :fb_database_authenticatable
end
Чтобы позволить вам либо создать пользователя, либо найти существующего пользователя на основе электронной почты 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
Я не думаю, что fb_database_authenticatable - это точное имя, но я оставлю это как упражнение для читателя. Еще одним упражнением является кэширование / сохранение токена доступа FB и, возможно, избегание RT-FB при каждом вызове. Следует отметить, что токен доступа из мобильного приложения и приложения rails будет отличаться, если вы выполните FB-аутентификацию с обеих сторон, что, как я подозреваю, большинство людей захотят сделать. Это, вероятно, влияет на вашу схему кэширования.
Я думаю, что это делает - счастливое кодирование.