【问题标题】:How to test or bypass Basic Auth in Rails 5 testing of controllers如何在 Rails 5 控制器测试中测试或绕过 Basic Auth
【发布时间】:2018-10-14 13:38:00
【问题描述】:

我想在 Rails 5 中测试激活了基本身份验证的控制器。 current official instruction(截至 2018 年 10 月 14 日)中解释的方式由于某种原因不起作用。 问答“Testing HTTP Basic Auth in Rails 2.2+”对于 Rails 5 来说似乎太旧了(至少对于默认值而言)。

这是一个重现此案例的简化示例。
我从全新安装的 Rails(最新稳定版本 5.2.1)通过脚手架制作了文章模型和相关资源:

bin/rails g scaffold Article title:string content:text

并在official guide之后向控制器添加了基本的身份验证功能;那么 ArticlesController 是这样的,当然可以:

# /app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  http_basic_authenticate_with name: "user1", password: "pass"
  before_action :set_article, only: [:show, :edit, :update, :destroy]

  def index
    @articles = Article.all
  end
end

official instruction 解释了测试基本身份验证的方法;你加 request.headers['Authorization'] 在控制器的测试文件中的 setup 块中,我这样做了:

# /test/controllers/articles_controller_test.rb
require 'test_helper'

class ArticlesControllerTest < ActionDispatch::IntegrationTest
  setup do
    request.headers['Authorization'] =
      ActionController::HttpAuthentication::Basic.encode_credentials("user1", "pass")
    @article = articles(:one)
  end

  test "should get index" do
    get articles_url
    assert_response :success
  end
end

但是,bin/rails test 失败如下:

# Running:

E

Error:
ArticlesControllerTest#test_should_get_index:
NoMethodError: undefined method `headers' for nil:NilClass
    test/controllers/articles_controller_test.rb:5:in `block in <class:ArticlesControllerTest>'

bin/rails test test/controllers/articles_controller_test.rb:10

显然,request 方法返回 nil,因此 request.headers['Authorization'] 失败。如果将语句放在 'testing-index' 块的顶部,则相同。

我发现request 在运行后 get articles_url 返回了一个合适的值,但到那时已经太晚了;我的意思是,到那时身份验证已经失败(显然)。通过一些谷歌搜索,似乎有些人使用@request@response 来代替,但我也发现它们与request 完全相同(预期?),也就是说,它们之前是零get.

在 Rails 5 中的控制器测试或集成测试中绕过或测试 Basic Auth 的方法是什么?

编辑:
current official instruction(截至 2018 年 10 月 14 日)”显然是错误的。见the answer

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-5 testng basic-authentication


    【解决方案1】:

    测试文档 were incorrecthave been updated 但尚未发布。 updated docs 阅读:

    注意:如果您按照基本身份验证部分中的步骤操作,则需要向每个请求标头添加授权以使所有测试通过:

    post articles_url, params: { article: { body: 'Rails is awesome!', title: 'Hello Rails' } }, headers: { Authorization: ActionController::HttpAuthentication::Basic.encode_credentials('dhh', 'secret') }
    

    【讨论】:

    • 这是一个完美的答案和解释!我确认它有效; n.b.,对于getparams 选项是可选的,因此可以使用:get articles_url, headers: { Authorization: ActionController::HttpAuthentication::Basic.encode_credentials('dhh', 'secret') }
    • 注解(Rails 5.2.1):delete 方法在 Basic Auth 失败时(例如,未给出!),与 postget 不同,后者会发出明确的错误消息。
    猜你喜欢
    • 2019-04-04
    • 1970-01-01
    • 2017-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多