辛纳屈 - API - 认证

59

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

3个回答

92

Sinatra 没有内置的身份验证支持。虽然有一些可用的 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_key?`方法返回false,则调用`error`后不会发生任何事情 - `error`内部调用`halt`,这将停止请求继续。

当然,在每个路由的开头重复检查并不理想。相反,您可以创建一个小扩展程序,向您的路由添加条件:

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
Todd Yandell,非常感谢您详细的回答和花费在其中的时间。我真的很感激。这确实有所帮助。Imran - Saim
创建一个小扩展似乎有些过度设计,使用 before filter 就足够了,因为后者可以选择应用哪些路由。你也可以通过 request.path_info 在过滤器的主体中判断。 - Robert

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正文,但作者提到了这一点。)

2

更新

如今,基于令牌的身份验证越来越受欢迎。 我建议使用JWT标准的Ruby实现,即ruby-jwt,用于简单的身份验证和授权。

gem 'jwt'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接