2010-08-13 17 views

risposta

88

Sinatra non ha il supporto di autenticazione integrato. Ci sono alcune gemme disponibili, ma la maggior parte sono progettate per l'autenticazione dell'utente (ad es. Per un sito Web). Per un'API, sembrano eccessivi. È abbastanza facile crearne uno tuo. Basta controllare i parametri di richiesta in ciascuno dei tuoi percorsi per vedere se contengono una chiave API valida e, in caso contrario, restituire un errore 401.

helpers do 
    def valid_key? (key) 
    false 
    end 
end 

get "/" do 
    error 401 unless valid_key?(params[:key]) 

    "Hello, world." 
end 

# $ irb -r open-uri 
# >> open("http://yourapp.com/api/?key=123") 
# OpenURI::HTTPError: 401 Unauthorized 

nulla dopo la chiamata a error accadrà se il metodo restituisce false valid_key? - error chiama halt internamente, che ferma la richiesta di continuare.

Ovviamente, non è ideale ripetere il controllo all'inizio di ogni percorso. Invece, è possibile creare una piccola estensione che aggiunge condizioni ai tuoi percorsi:

class App < Sinatra::Base 
    register do 
    def check (name) 
     condition do 
     error 401 unless send(name) == true 
     end 
    end 
    end 

    helpers do 
    def valid_key? 
     params[:key].to_i % 2 > 0 
    end 
    end 

    get "/", :check => :valid_key? do 
    [1, 2, 3].to_json 
    end 
end 

Se si desidera solo l'autenticazione su tutti i vostri percorsi, utilizzare un gestore before:

before do 
    error 401 unless params[:key] =~ /^xyz/ 
end 

get "/" do 
    {"e" => mc**2}.to_json 
end 
+7

Todd Yandell, grazie mille per la risposta dettagliata e per il tempo che ci avete dedicato. Ho davvero apprezzato. È davvero utile Imran – Saim

+0

La creazione di un'estensione piccola sembra eccessiva, un filtro precedente è sufficiente, poiché quest'ultimo ha l'opzione su quali percorsi applicare. Puoi anche dirlo dall'interno del corpo del filtro request.path_info. – Robert

2

http://www.secondforge.com/blog/2014/11/05/simple-api-authentication-in-sinatra/ ha un po 'più dettagliata risposta che utilizza i token dell'utente.

Questo è un passaggio più complicato di una chiave API, ma è necessario se l'API richiede l'autenticazione per accedere a un utente per eseguire operazioni quali la modifica di un nome/email/password o l'accesso alle informazioni per utente. (cioè azioni API "private"). È inoltre possibile revocare/scadere i token utente per permettere alle persone log out, ecc

class App < Sinatra::Base 

    before do 
    begin 
     if request.body.read(1) 
     request.body.rewind 
     @request_payload = JSON.parse request.body.read, { symbolize_names: true } 
     end 
    rescue JSON::ParserError => e 
     request.body.rewind 
     puts "The body #{request.body.read} was not JSON" 
    end 
    end 

    post '/login' do 
    params = @request_payload[:user] 

    user = User.find(email: params[:email]) 
    if user.password == params[:password] #compare the hash to the string; magic 
     #log the user in 
    else 
     #tell the user they aren't logged in 
    end 
    end 
end 

(Vale la pena notare che è più comune di leggere le credenziali da un header HTTP al posto del corpo JSON, ma l'autore afferma che .)