1

我正在尝试实现基本的 http 身份验证,但我需要根据已通过身份验证的帐户的状态返回不同的 HTTP 状态代码。我正在使用 Sinatra 来托管 API,这就是我的应用程序的样子:

require 'rubygems'
require 'bundler/setup'
require 'sinatra'
require 'active_record'
require 'openssl'

# Define the paths that the application responds to, and include the authentication mechanism to provide
# basic HTTP authentication using the Rack middleware.
use Rack::Auth::Basic do |username, password|
  result = LoginApi::User.authenticate(username, password)

  # Check the status of the user we just authenticated. If he is banned or unverified then we
  # need to return special responses.
  throw :halt, [403, 'User is banned'] if LoginApi::AuthUser.user.banned?
  throw :halt, [412, 'User is not verified'] unless LoginApi::AuthUser.user.verified?

  # Return the result if no exceptions were raised in the meanwhile
  result
end

# This action responds on the root of the application and will return the basic authentication of a User
# in the headers. This is done by Rack::Auth, which requires the credentials to be sent in the initial
# call so they can be verified by the application
get '/' do
  headers \
    "X-UserID" => "#{LoginApi::AuthUser.user.id}|",
    "X-P1" => "#{LoginApi::AuthUser.p1}",
    "X-P2" => "#{LoginApi::AuthUser.p2}"
end

所以基本上,它返回一个状态 200 表示 ok 身份验证,403 表示被禁止的用户,412 表示未验证的用户,如果身份验证失败则返回 400。

问题是我无法让我的测试正常工作。正常身份验证的测试工作正常并通过,但需要检查自定义 HTTP 状态响应的测试失败,并出现以下错误:

ArgumentError: uncaught throw :halt ./app.rb:23:in throw' ./app.rb:23:inblock in ' ./features/step_definitions/when_steps.rb:8:in/^I make the call to the API$/' ./features/banned.feature:8:in当我调用 API 时

跳过步骤

有人可以解释一下我做错了什么或错过了什么以使其按我的意愿工作吗?

4

1 回答 1

0

将禁止和未验证的检查移至动作主体,并在那里处理结果。

可惜我不能在机架助手中做到这一点......

于 2012-05-23T13:35:20.243 回答