Ho appena fatto questo, ma non ho mai visto una soluzione end-to-end.
Questo indirizzo punto 3. 1 & 2 sono facilmente realizzabili con elaborati e documentati altrove.
Non troppo difficile aggiungere l'autenticazione FB alla tua app Web, le istruzioni sono su github per omniauth e omniauth-facebook.
Credo che il seguente si erge da solo, senza fare l'integrazione omniauth-facebook, se si vuole fare in questo modo. Questo è simile ad altri approcci là fuori. La mia idea era di tentare di usare il modello di idea il più vicino possibile.
Avrai bisogno della gemma fb_graph.
Sul client mobile, si autentica correttamente con FB e si inserisce il token di accesso restituito nell'intestazione delle richieste http. Ho usato l'intestazione fb_access_token. Proprio come l'autenticazione di base, ti consigliamo di inviarlo su SSL per evitare lo sniffing del token. L'utilizzo dell'intestazione mi consente di scambiare l'autenticazione di base e l'autenticazione FB senza modificare le richieste, ma se preferisci puoi utilizzare un parametro.
Questa soluzione implementa una strategia di guardia che si basa sulla strategia di autenticazione Authenticatable. La differenza qui è il fatto che questa strategia utilizza un'intestazione HTTP chiamata fb_access_token contenente la stringa token di accesso di Facebook che è stata recuperata utilizzando l'applicazione mobile.
Una volta saputo questo, il codice è piuttosto semplice.
In un file, nella directory config/initializers, aggiungere quanto segue. Mi è capitato di chiamare il mio 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)
in config/inizializzatori, aggiungere il seguente al devise.rb:
config.warden do |manager|
manager.default_strategies(:scope => :user).unshift :fb_database_authenticatable
end
Per consentire di creare un utente o di trovare un utente esistente in base alla e-mail FB, aggiungere il segue al proprio modello utente:
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
non credo fb_database_authenticatable è un nome preciso, ma lascio che come esercizio per il lettore. Un altro esercizio consiste nella memorizzazione nella cache/memorizzazione del token di accesso FB, e forse evitando il RT in FB con ogni chiamata. Dovresti notare che il token di accesso dall'app per dispositivi mobili e dall'app per i binari sarà diverso se esegui l'autenticazione FB su entrambi i lati, il che sospetto che la maggior parte delle persone vorrà fare. Ciò probabilmente influisce sul tuo schema di caching.
Penso che lo faccia, felice codifica.
cosa da notare: Le autorizzazioni di base per l'utilizzo di un account di FB non fornire l'indirizzo email Dovrai chiedere esplicitamente all'utente questa autorizzazione. – beeudoublez
Buon punto @beeudoublez, è esattamente ciò che ho fatto nella mia app. – Matt