Perl LWP::Simple::get($url) 对某些 url 不起作用

use*_*262 0 perl

我正在使用 LWP::Simple::get($url) 库从网页访问数据。问题是 get 函数不适用于以下 url。下面是代码片段:

#!/usr/bin/perl

use LWP::Simple;
use JSON;
use Data::Dumper;

my $url = "https://www.cryptopia.co.nz/api/GetCurrencies";

my $json = get( $url);
die "Could not get $url!" unless defined $json;

my $decoded_json = decode_json($json);
print Dumper($decoded_json);
Run Code Online (Sandbox Code Playgroud)

运行此代码后,它会出现以下错误:

无法获取https://www.cryptopia.co.nz/api/GetCurrencies!

当我用 : 替换 url 时,$url = "https://api.coinmarketcap.com/v1/ticker/"它工作正常。请你告诉我根本原因是什么以及我如何解决它。此外,代码片段中提到的 url 工作过一次,现在突然不起作用。

Ste*_*ich 5

这与这个问题本质上是相同的,仅适用于 Perl LWP 而不是 NodeJS。

问题是目标站点的设置已损坏并且缺少中间证书。这可以从SSLabs 报告中看出:

此服务器的证书链不完整。等级上限为 B。

要解决此问题,您有两个安全选项和一个不安全选项。不安全但不幸的是,经常提出的选项是禁用所有证书验证。不要这样做,因为它会使您的应用程序容易受到中间人攻击。

下一个选项是拥有自己的信任库,其中包括所有必要的证书,即根 CA 和缺少的中间 CA:

use strict;
use warnings;
use LWP::UserAgent;
use IO::Socket::SSL;
my $ua = LWP::UserAgent->new;
$ua->ssl_opts(
    SSL_ca_file => 'myca.pem', 
    # disable OCSP stapling since it results in problems with this site
    SSL_ocsp_mode => SSL_OCSP_NO_STAPLE
);
my $resp = $ua->get('https://www.cryptopia.co.nz/api/GetCurrencies');
print $resp->decoded_content;
Run Code Online (Sandbox Code Playgroud)

myca.pem在这种情况下,是中间“COMODO RSA 扩展验证安全服务器 CA”和根“COMODO RSA 证书颁发机构”的证书的 PEM 表示的串联。我已经在 Pastebin 提供了它,这里

第三个选项是仅信任此特定叶证书。使用时,这将信任使用此证书的服务器,无论证书是否过期、吊销、主机名与 URL 不匹配或(在这种情况下)由于缺少中间证书而无法构建信任链:

use strict;
use warnings;
use LWP::UserAgent;
use IO::Socket::SSL;

my $ua = LWP::UserAgent->new;
$ua->ssl_opts(
    SSL_fingerprint => 'sha256$70bca153ac950b8fa92d20f04dceca929852c42dc1d51bdc3c290df256ae05d3',
    SSL_ocsp_mode => SSL_OCSP_NO_STAPLE,
);
my $resp = $ua->get('https://www.cryptopia.co.nz/api/GetCurrencies');
print $resp->decoded_content;
Run Code Online (Sandbox Code Playgroud)

您在此处看到的指纹是您在查看证书时也可以在浏览器中看到的指纹。