2010-08-13 178 views

回答

88

Sinatra沒有內置的認證支持。有一些寶石可用,但大多數都是爲用戶認證而設計的(即用於網站)。對於一個API來說,它們看起來像是矯枉過正。製作你自己的作品很容易。只需檢查每個路由中的請求參數,看看它們是否包含有效的API密鑰,如果不是,則返回401錯誤。 error呼籲halt內部,其停止持續的要求 - 如果你的valid_key?方法返回false調用error

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 

不會發生任何事情。

當然,在每條路線的開始重複檢查並不理想。相反,你可以創建一個小的擴展,增加了條件,以你的路由:

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 

如果你只是想上的所有路由認證,使用before處理程序:

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

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

託德Yandell,非常感謝您的詳細的答案和你花在它上面的時間。我真的很感激。這真的很有幫助。 Imran – Saim 2010-08-16 11:30:53

+0

創建一個小擴展似乎過度使用,過濾之前就足夠了,因爲後者可以選擇應用哪些路由。您也可以通過request.path_info從過濾器的主體中知道。 – Robert 2015-05-13 09:13:29

2

http://www.secondforge.com/blog/2014/11/05/simple-api-authentication-in-sinatra/有一個稍微更詳細使用用戶令牌的答案。

這一步比API密鑰更復雜,但必要的,如果你的API需要認證登錄用戶做的事情,如編輯名稱/電子郵件/密碼,或訪問每用戶信息。 (即「私人」API行動)。您也可以撤銷/到期用戶令牌讓人註銷等

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 

(這是值得大家注意的,它是更常見的是從一個HTTP頭,而不是JSON體讀取的憑據,但筆者提到, 。)