【发布时间】:2011-03-29 15:04:27
【问题描述】:
我们将在 Sinatra 中开发一个小的 API 应用程序。有哪些身份验证选项可用于保护 API 调用?
【问题讨论】:
标签: api authentication sinatra
我们将在 Sinatra 中开发一个小的 API 应用程序。有哪些身份验证选项可用于保护 API 调用?
【问题讨论】:
标签: api authentication sinatra
Sinatra 没有内置的身份验证支持。有一些 gems 可用,但大多数都是为用户身份验证而设计的(即用于网站)。对于 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
【讨论】:
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 正文中读取凭据更为常见,但作者提到了这一点。)
【讨论】:
【讨论】: