我想访问一个需要用户名/密码的URL。 我想尝试使用curl访问它。 现在我正在做类似的事情:
curl http://api.somesite.com/test/blah?something=123
我得到一个错误。 我想我需要指定用户名和密码以及上述命令。
我怎样才能做到这一点?
#1楼
还是相同但语法不同
curl http://username:password@api.somesite.com/test/blah?something=123
#2楼
您也可以通过以下方式发送用户名:
curl -u USERNAME http://server.example
然后,Curl会询问您密码,并且密码在屏幕上将不可见(或者是否需要复制/粘贴命令)。
#3楼
使用-u
标志包含用户名,curl会提示输入密码:
curl -u username http://example.com
您还可以在命令中包含密码,但是您的密码将在bash历史记录中显示:
curl -u username:password http://example.com
#4楼
这样做更安全:
curl --netrc-file my-password-file http://example.com
...因为在命令行上传递普通用户/密码字符串是一个坏主意。
密码文件的格式为(按man curl
):
machine <example.com> login <username> password <password>
注意:
- 机器名称不得包含
https://
或类似名称! 只是主机名。 - “
machine
”,“login
”和“password
”只是关键词; 实际信息是这些关键字之后的内容。
#5楼
为了使密码至少不会在您的.bash_history
弹出:
curl -u user:$(cat .password-file) http://example-domain.tld
#6楼
简而言之,最安全的方法是使用环境变量来存储/检索凭据。 因此,curl命令如下:
curl -Lk -XGET -u "${API_USER}:${API_HASH}" -b cookies.txt -c cookies.txt -- "http://api.somesite.com/test/blah?something=123"
然后,将调用您的WWW_Authentication
api并使用带有API_USER
和API_HASH
的Base64编码值的http WWW_Authentication
头API_HASH
。 -Lk
只是告诉curl遵循http 30x重定向并使用不安全的tls处理(即忽略ssl错误)。 而双--
仅仅是bash的语法糖停止处理命令行标志。 此外, -b cookies.txt
和-c cookies.txt
标志使用-b
发送cookie和-c
在本地存储cookie来处理cookie。
#7楼
如果您使用的是具有Gnome密钥环应用程序的系统,那么避免直接暴露密码的解决方案是使用gkeyring.py从密钥环中提取密码:
server=server.example.com
file=path/to/my/file
user=my_user_name
pass=$(gkeyring.py -k login -tnetwork -p user=$user,server=$server -1)
curl -u $user:$pass ftps://$server/$file -O
#8楼
您可以使用以下命令:
curl -u user-name -p http://www.example.com/path-to-file/file-name.ext > new-file-name.ext
然后将触发HTTP密码。
参考: http : //www.asempt.com/article/how-use-curl-http-password-protected-site
#9楼
为了安全地在脚本中传递密码(即防止其与ps auxf或日志一起显示),您可以使用-K-标志(从stdin读取配置)和heredoc来执行:
curl --url url -K- <<< "--user user:password"
#10楼
我对bash(Ubuntu 16.04 LTS)有相同的需求,答案中提供的命令在我的情况下无法正常工作。 我不得不使用:
curl -X POST -F 'username="$USER"' -F 'password="$PASS"' "http://api.somesite.com/test/blah?something=123"
仅当您使用变量时,才需要在-F
参数中使用双引号,因此从命令行... -F 'username=myuser' ...
就可以了。
相关安全声明:正如Mark Ribau先生在评论中指出的那样,此命令在进程列表中显示密码($ PASS变量,已展开)!
#11楼
curl -X GET -u username:password {{ http://www.example.com/filename.txt }} -O
#12楼
其他答案也建议netrc根据我阅读的内容指定用户名和密码。 以下是一些语法详细信息:
https://ec.haxx.se/zh-CN/curl-netrc.html
像其他答案一样,我想强调必须注意此问题的安全性。
尽管我不是专家,但我发现这些链接很有见地:
https://ec.haxx.se/cmdline-passwords.html
总结一下:
使用协议的加密版本 (HTTPS与HTTP)(FTPS与FTP)可以帮助避免网络泄漏。
使用netrc可以帮助避免命令行泄漏。
更进一步,看来您也可以使用gpg加密netrc文件
https://brandur.org/fragments/gpg-curl
这样,您的凭据就不会作为纯文本“处于静止状态”(存储)。
#13楼
非常简单,请执行以下操作:
curl -X GET/POST/PUT <URL> -u username:password
#14楼
通常CURL命令称为
curl https://example.com\?param\=ParamValue -u USERNAME:PASSWORD
如果您没有任何密码,或者想跳过命令提示符以要求输入简单密码,请将密码部分留空。
即curl https://example.com\\?param\\=ParamValue -u USERNAME:
#15楼
提示将凭证传递给curl的最安全方法是提示插入凭证。 如先前建议的那样传递用户名时,会发生这种情况( -u USERNAME
)。
但是,如果您不能以这种方式传递用户名怎么办? 例如,用户名可能需要是url的一部分,而只有密码是json负载的一部分。
tl; dr:在这种情况下,这是安全使用curl的方法:
read -p "Username: " U; read -sp "Password: " P; curl --request POST -d "{\"password\":\"${P}\"}" https://example.com/login/${U}; unset P U
read
将从命令行提示输入用户名和密码,并将提交的值存储在两个变量中,这些变量可以在后续命令中引用,最后未设置。
我将详细说明为什么其他解决方案不理想。
为什么环境变量不安全
- 由于该环境对于进程是隐式可用的,因此无法跟踪环境变量内容的访问和公开模式(ps -eww)
- 应用程序通常会捕获整个环境并记录下来以进行调试或监视(有时在磁盘上以纯文本格式记录日志文件,尤其是在应用程序崩溃后)
- 环境变量被传递给子进程(因此违反了最小特权原则)
- 维护它们是一个问题:新工程师不知道他们在那里,也不了解周围的需求-例如,不要将其传递给子流程-因为它们没有得到执行或记录。
为什么直接在命令行上将其键入命令中是不安全的,因为您的秘密最终将被运行ps -aux
的任何其他用户看到,因为它列出了为每个当前正在运行的进程提交的命令。 同样是因为您的密钥随后出现在bash历史记录中(一旦shell终止)。
为什么将其包含在本地文件中是不安全的,对此文件进行严格的POSIX访问限制可以减轻这种情况下的风险。 但是,它仍然是文件系统上的文件,静态时未加密。
#16楼
这比OP要求的要多得多,但是由于这是安全地将密码传递给curl
的最佳结果,因此我在这里添加了这些解决方案,供其他到达此地的人使用。
注意: -s
arg for read
命令不是POSIX,因此并非在所有地方都可用,因此下面将不使用它。 我们将改用stty -echo
和stty echo
。
注意:如果在函数中,则下面的所有bash变量都可以声明为locals,而不是取消设置。
注意: perl
在我尝试过的所有系统上都相当普遍,这是因为它对许多事情都具有依赖性,而ruby
和python
不是,所以在这里使用perl
。 如果可以保证在其中执行ruby
/ python
,则可以将perl
命令替换为其等效命令。
注意:在macOS 10.14.4上的bash
3.2.57中进行了测试。 其他外壳程序/安装可能需要一些小的翻译。
安全地提示用户输入(可重复使用的)密码以进行卷曲。 如果需要多次调用curl,则特别有用。
对于现代外壳, echo
是内置的(通过检查which 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