2011-02-14 13 views
11

A causa di Facebook che depreca il nuovo FBML, sto cercando un nuovo modo per creare una scheda "rivela" (una scheda della pagina che mostra una versione per i fan e un'altra per i non fan) . Facebook ha aggiunto dati al signed_request:Decodifica della richiesta firmata di Facebook in Ruby/Sinatra

Quando un utente seleziona la tua applicazione nel menu a sinistra, l'applicazione riceverà il parametro signed_request con uno parametro aggiuntivo, pagina, una matrice JSON che contiene l'ID della pagina Facebook nella scheda è ospitato all'interno di , un valore booleano ('piaciuto') che indica Pagina e un booleano ('admin') indicante se l'utente ha o meno la l'utente è un 'amministratore' della Pagina insieme alle informazioni utente array.

Sono in grado di leggere la sanzione firmata, ma devo elaborarla con la decodifica base64url per ottenere il JSON corretto. Inoltre, ho trovato nella mia ricerca che il JSON è formattato in modo improprio per Ruby, quindi deve essere modificato prima di decodificarlo. Ecco il codice corrente (sto solo la stampa della richiesta firmata in index.erb per ora):

helpers do 
    def base64_url_decode str 
    encoded_str = str.gsub('-','+').gsub('_','/') 
    encoded_str += '=' while !(encoded_str.size % 4).zero? 
    Base64.decode64(encoded_str) 
    end 

    def decode_data str 
    encoded_sig, payload = str.split('.') 
    data = ActiveSupport::JSON.decode base64_url_decode(payload) 
    end 
end 

get '/' do 
    signed_request = params[:signed_request] 
    @signed_request = decode_data(signed_request) 
    erb :index 
end 

Sto cercando di mantenere l'applicazione il più leggero possibile ed evitare di usare una libreria completa Facebook come questo ha vinto essere un'applicazione completa (solo una scheda) e non richiederà autorizzazioni aggiuntive da parte degli utenti. Sono gradite anche eventuali raccomandazioni sul mio metodo di rilevamento dei fan.

risposta

7

Mi sono imbattuto in questo prima. Hai solo bisogno di pad alla fine della stringa di payload con = segni fino a quando la sua lunghezza è divisibile per 4.

Ciò funzionerà:

payload += '=' * (4 - payload.length.modulo(4)) 

(non sono sicuro dove/se questo è documentato da Facebook, ma qualcuno su IRC me ne ha parlato all'inizio del 2011, e in effetti ho trovato tale padding nel codice sorgente di varie librerie client di Facebook)

+0

Questo sembra vicina, ma non corretto. Si desidera eseguire il rilievo solo con 1 o 2 caratteri, mai con 3 o 4, ad es. se payload.module (4) è zero, non eseguire il pad. http://en.wikipedia.org/wiki/Base64 –

+0

Nota: il riempimento con quattro '=' sembra interrompersi se si utilizza strict_decode64 o urlsafe_decode64, ma è tollerato dalla decodifica64. –

6

Io uso la libreria fbgraph che funziona con il metodo parse_signed_request.

+0

Ha funzionato perfettamente, tnx –

2

La risposta da dorkitude era corretta. Ho appena avuto lo stesso problema e lo ho riempito con un "=" funzionante.

È possibile verificare ciò utilizzando:

Base64.strict_decode64(invalid_payload) 
=> ArgumentError: invalid base64 
Problemi correlati