2010-08-13 180 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体读取的凭据,但笔者提到, 。)