Sinatra-API-身份验证
我们将在Sinatra中开发一个小API应用程序。保护API调用的身份验证选项有哪些?Sinatra没有内置的身份验证支持。有一些gem可用,但大多数gem是为用户身份验证而设计的(即用于网站)。对于一个API来说,它们似乎有些矫枉过正。做你自己的很容易。只需检查每个路由中的请求参数,查看它们是否包含有效的API密钥,如果不包含,则返回401错误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
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'