我想访问一个需要用户名/密码的URL。我想用curl访问它。现在我正在做的事情是:
curl http://api.somesite.com/test/blah?something=123
我得到一个错误。我想我需要在上面的命令中指定用户名和密码。
我该怎么做呢?
我想访问一个需要用户名/密码的URL。我想用curl访问它。现在我正在做的事情是:
curl http://api.somesite.com/test/blah?something=123
我得到一个错误。我想我需要在上面的命令中指定用户名和密码。
我该怎么做呢?
当前回答
如果你的服务器支持基本认证,你可以这样做:
printf 'header="Authorization: Basic %s"' "$(base64 --wrap=0 credentials)"|
curl --config - https://example.org
凭据是存储用户名和密码的文件,格式为username:password。
该解决方案的好处:
不需要转义特殊字符 适用于任何密码,即使它包含空格、引号、反斜杠或其他特殊字符,因此它也可以安全地用于不控制输入的脚本 在带有内置printf的shell中,登录数据不会显示在进程列表中
如果你的shell没有printf作为内置命令,你可以这样做,以避免登录数据出现在进程列表中:
{ printf 'header="Authorization: Basic '; base64 --wrap=0 credentials; printf '"'; }|
curl --config - https://example.org
其他回答
更安全的做法是:
curl --netrc-file my-password-file http://example.com
...由于在命令行上传递普通的用户/密码字符串,这是一个坏主意。
密码文件的格式为(按照man curl):
machine <example.com> login <username> password <password>
注意:
机器名不能包含https://或类似!只有主机名。 “machine”、“login”和“password”只是关键词;真正的信息是那些关键字之后的东西。
其他回答建议netrc指定用户名和密码,根据我所读到的,我同意。下面是一些语法细节:
https://ec.haxx.se/usingcurl-netrc.html
和其他回答一样,我想在这个问题上强调,要注意安全。
虽然我不是专家,但我发现这些链接很有见地:
https://ec.haxx.se/cmdline-passwords.html
总结:
使用加密版本的协议(HTTPS vs HTTP) (FTPS vs FTP)可以帮助避免网络泄漏。
使用netrc可以帮助避免命令行泄漏。
更进一步,似乎还可以使用gpg加密netrc文件
https://brandur.org/fragments/gpg-curl
这样,您的凭据就不会“静止”(存储为纯文本)。
您应该确定身份验证类型。
如果是摘要认证,http头为:
GET /xxxxxxxxxxx HTTP/1.1
Host: 192.168.3.142
User-Agent: Go-http-client/1.1
Authorization: Digest username="admin", realm="admin@51200304-49-test", nonce="5.1722929000077545", uri="/xxxxxxxxxxx", response="52d30eba90820f2c4fa4d3292a4a7bbc", cnonce="f11900fe0906e3899e0cc431146512bb", qop=auth, nc=00000001
Accept-Encoding: gzip
你可以使用——digest选项:
curl --digest -u 'username:password' 'http://xxxxxxxxxxx'
你也可以这样发送用户名:
curl -u USERNAME http://server.example
然后Curl将要求您输入密码,并且密码将不会在屏幕上显示(或者如果您需要复制/粘贴该命令)。
这比OP要求的要多得多,但由于这是安全传递密码给curl的顶级结果,我在这里添加了这些解决方案,以供其他人到达这里搜索。
注意:-s arg for read命令不是POSIX,所以不是到处都可用,所以下面不使用。我们将使用stty -echo和stty echo代替。
注意:如果在函数中,下面所有bash变量都可以声明为局部变量,而不是不设置。
注意:perl在我尝试过的所有系统上都是可用的,因为它是许多东西的依赖项,而ruby和python不是,所以在这里使用perl。如果你能保证在ruby/python中执行此操作,你可以用它们的等价命令替换perl命令。
注意:在macOS 10.14.4上的bash 3.2.57中测试。其他shell /安装可能需要一些小的转换。
安全地提示用户输入要传递给curl的(可重用的)密码。如果需要多次调用curl,则特别有用。
对于现代shell, echo是内置的(检查通过哪个echo):
url='https://example.com'
printf "Username: "
read username
printf "Password: "
stty -echo # disables echoing user input, POSIX equivalent for 'read -s'
read pass
printf "\n" # we need to move the line ahead
stty echo # re-enable echoing user input
echo ${pass} | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-
unset username
unset pass
对于旧的shell, echo类似于/bin/echo(无论它所回显的是什么,都可以在进程列表中看到): 此版本不能重复使用密码,请参见下方。
url='https://example.com'
printf "Username: "
read username
printf "Password: "
stty -echo # disables echoing user input, POSIX equivalent for 'read -s'
perl -e '
my $val=<STDIN>;
chomp $val;
print STDERR "\n"; # we need to move the line ahead, but not send a newline down the pipe
print $val;
' | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-
stty echo # re-enable echoing user input
unset username
如果您碰巧需要将密码临时存储到一个文件中,以便在清除它之前为多个命令重用它(例如,因为您正在使用用于代码重用的函数,不想重复代码,并且不能通过echo传递值)。(是的,这种形式看起来有点不自然,它们不是不同库中的函数;我试图将它们减少到显示它所需的最小代码。)
当echo是内置的(这是特别人为的,因为echo是内置的,但提供了完整性):
url='https://example.com'
filepath="$(mktemp)" # random path, only readable by current user
printf "Username: "
read username
printf "Password: "
stty -echo # disables echoing user input, POSIX equivalent for 'read -s'
read pass
echo "${pass}" > "${filepath}"
unset pass
printf "\n" # we need to move the line ahead
stty echo # re-enable echoing user input
cat "${filepath}" | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-
rm "${filepath}" # don't forget to delete the file when done!!
unset username
当echo类似于/bin/echo时:
url='https://example.com'
filepath="$(mktemp)" # random path, only readable by current user
printf "Username: "
read username
printf "Password: "
stty -echo # disables echoing user input, POSIX equivalent for 'read -s'
$(perl -e '
my $val=<STDIN>;
chomp $val;
open(my $fh, ">", $ARGV[0]) or die "Could not open file \"$ARGV[0]\" $\!";
print $fh $val;
close $fh;
' "$filepath")
printf "\n" # we need to move the line ahead
stty echo # re-enable echoing user input
cat "${filepath}" | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-
rm "${filepath}" # don't forget to delete the file when done!!
unset username