Sinatra-API-身份验证

Sinatra-API-身份验证,api,authentication,sinatra,Api,Authentication,Sinatra,我们将在Sinatra中开发一个小API应用程序。保护API调用的身份验证选项有哪些?Sinatra没有内置的身份验证支持。有一些gem可用,但大多数gem是为用户身份验证而设计的(即用于网站)。对于一个API来说,它们似乎有些矫枉过正。做你自己的很容易。只需检查每个路由中的请求参数,查看它们是否包含有效的API密钥,如果不包含,则返回401错误 helpers do def valid_key? (key) false end end get "/" do error 4

我们将在Sinatra中开发一个小API应用程序。保护API调用的身份验证选项有哪些?

Sinatra没有内置的身份验证支持。有一些gem可用,但大多数gem是为用户身份验证而设计的(即用于网站)。对于一个API来说,它们似乎有些矫枉过正。做你自己的很容易。只需检查每个路由中的请求参数,查看它们是否包含有效的API密钥,如果不包含,则返回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
如果
valid\u key?
方法返回false-
error
内部调用
halt
,则调用
error
后不会发生任何事情,这会阻止请求继续

当然,在每条路线开始时重复检查并不理想。相反,您可以创建一个小型扩展,为路线添加条件:

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
有一个更详细的答案,使用用户令牌

这是比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
class-Appe
请求。身体。倒带
放置“body{request.body.read}不是JSON”
结束
结束
post'/login'do
params=@request_有效载荷[:user]
user=user.find(email:params[:email])
如果user.password==params[:password]#将哈希值与字符串进行比较;魔术
#让用户登录
其他的
#告诉用户他们没有登录
结束
结束
结束

(值得注意的是,从HTTP头而不是JSON体读取凭据更为常见,但作者提到了这一点。)

更新

如今,基于令牌的身份验证越来越流行。 我建议使用JWT标准的ruby实现进行简单的身份验证和授权

gem 'jwt'

托德·扬德尔,非常感谢你的详细回答和花在上面的时间。我真的很感激。这真的很有帮助。创建一个小的扩展似乎有些过分,一个before过滤器就足够了,因为后者可以选择应用哪些路由。您还可以通过request.path\u info从过滤器的主体中判断这一点。
gem 'jwt'