如何在 Ruby 中通过 HTTPs 进行基本身份验证?

问题描述 投票:0回答:3

经过大量研究后,我发现了一些似乎有效的解决方案,但不适合我......

例如,我有这个脚本:

require 'net/http'
require "net/https"

@http=Net::HTTP.new('www.xxxxxxx.net', 443)
@http.use_ssl = true
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
@http.start() {|http|
    req = Net::HTTP::Get.new('/gb/PastSetupsXLS.asp?SR=31,6')
    req.basic_auth 'my_user', 'my_password'
    response = http.request(req)
    print response.body
}

当我运行它时,它会给我一个请求身份验证的页面,但是如果我在浏览器中写入以下 URL,我就可以毫无问题地进入该网站:

https://my_user:[email protected]/gb/PastSetupsXLS.asp?SR=31,6

我也尝试过 open-uri:

module OpenSSL
    module SSL
        remove_const :VERIFY_PEER
    end
end
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE

def download(full_url, to_here)
    writeOut = open(to_here, "wb") 
    writeOut.write(open(full_url, :http_basic_authentication=>["my_user", "my_password"]).read) 
    writeOut.close 
end

download('https://www.xxxxxxx.net/gb/PastSetupsXLS.asp?SR=31,6', "target_file.html")

但结果是一样的,网站要求用户进行身份验证。 我做错了什么有什么提示吗?我必须用 Base 64 对密码进行编码吗?

ruby https basic-authentication
3个回答
51
投票

我根据 Net::HTTP 文档中给出的示例编写了一段代码,并在我的本地 WAMP 服务器上进行了测试 - 它工作正常。这是我所拥有的:

require 'net/http'
require 'openssl'

uri = URI('https://localhost/')

Net::HTTP.start(uri.host, uri.port,
  :use_ssl => uri.scheme == 'https', 
  :verify_mode => OpenSSL::SSL::VERIFY_NONE) do |http|

  request = Net::HTTP::Get.new uri.request_uri
  request.basic_auth 'matt', 'secret'

  response = http.request request # Net::HTTPResponse object

  puts response
  puts response.body
end

我的

.htaccess
文件如下所示:

AuthName "Authorization required"
AuthUserFile c:/wamp/www/ssl/.htpasswd
AuthType basic
Require valid-user

我的

.htpasswd
只是用
htpasswd -c .htpasswd matt
生成的一行代码,用于密码“秘密”。当我运行代码时,我得到“200 OK”和index.html 的内容。如果删除
request.basic_auth
行,则会收到 401 错误。

更新:

正如 @stereoscott 在评论中指出的,我在示例中使用的

:verify_mode
值 (
OpenSSL::SSL::VERIFY_NONE
) 对于生产来说并不安全。

OpenSSL::SSL::SSLContext文档中列出的所有可用选项为:VERIFY_NONE、VERIFY_PEER、VERIFY_CLIENT_ONCE、VERIFY_FAIL_IF_NO_PEER_CERT,其中(根据OpenSSL 文档)仅前两个在客户端模式下使用.

所以

VERIFY_PEER
应该在生产中使用,这是默认的顺便说一句,所以你可以完全跳过它。


8
投票
以下是最终为我工作的内容:

require "uri" require "net/http" url = URI("https://localhost/") https = Net::HTTP.new(url.host, url.port) https.use_ssl = true request = Net::HTTP::Get.new(url) request["Authorization"] = "Basic " + Base64::encode64("my_user:my_password") response = https.request(request) puts response.read_body
我通过在 

Postman 中构建一个新的 HTTP 请求、指定 URL、选择“基本身份验证”授权类型并输入凭据来想出此方法。

单击“代码”图标 (

</>

) 并选择“Ruby - Net::HTTP”将生成一个代码片段,为您提供上面的输出。

邮递员负责对凭据进行编码,但是

这个答案帮助我动态设置这些值。您也可以省略“cookie”键作为请求的一部分。


0
投票
对于基本身份验证,您可以使用

Base64.strict_encode64


request["Authorization"] = "Basic #{::Base64.strict_encode64("#{user_name}:#{password}")}"
受到

https://apidock.com/rails/v5.2.3/ActionController/HttpAuthentication/Basic/encode_credentials源代码的启发

© www.soinside.com 2019 - 2024. All rights reserved.