使用cURL和用户名和密码?

时间:2010-04-07 18:22:49

标签: curl credentials

我想访问需要用户名/密码的网址。我想尝试用curl访问它。现在我正在做类似的事情:

curl http://api.somesite.com/test/blah?something=123

我收到错误。我想我需要指定一个用户名和密码以及上面的命令。

我该怎么做?

17 个答案:

答案 0 :(得分:587)

使用-u标志包含用户名,curl将提示输入密码:

curl -u username http://example.com

您也可以在命令中包含密码,但是密码将在bash历史记录中显示:

curl -u username:password http://example.com

答案 1 :(得分:206)

更安全:

curl --netrc-file my-password-file http://example.com

...因为在命令行上传递普通用户/密码字符串是个坏主意。

密码文件的格式为(按man curl):

machine <example.com> login <username> password <password>

注意:

  1. 机器名称必须包括https://或类似名称!只是主机名。
  2. 单词&#39; machine&#39;,&#39; login&#39;,&#39; password&#39;只是关键词;实际信息就是这些关键词之后的内容。

答案 2 :(得分:69)

或者同样的事情,但语法不同

curl http://username:password@api.somesite.com/test/blah?something=123

答案 3 :(得分:60)

您也可以通过以下方式发送用户名:

curl -u USERNAME http://server.example

然后Curl将要求您输入密码,并且屏幕上将不会显示密码(或者如果您需要复制/粘贴命令)。

答案 4 :(得分:16)

要在脚本中安全地传递密码(即防止它显示ps auxf或日志),您可以使用-K-标志(从stdin读取配置)和heredoc:

curl --url url -K- <<< "--user user:password"

答案 5 :(得分:11)

curl -X GET -u username:password  {{ http://www.example.com/filename.txt }} -O

答案 6 :(得分:7)

要让密码至少不会弹出.bash_history

curl -u user:$(cat .password-file) http://example-domain.tld

答案 7 :(得分:6)

简单而简单地说,最安全的方法是使用环境变量来存储/检索您的凭据。因此卷曲命令如:

curl -Lk -XGET -u "${API_USER}:${API_HASH}" -b cookies.txt -c cookies.txt -- "http://api.somesite.com/test/blah?something=123"

然后调用您的restful api并传递带有WWW_AuthenticationAPI_USER的Base64编码值的http API_HASH标头。 -Lk只是告诉curl遵循http 30x重定向并使用不安全的tls处理(即忽略ssl错误)。虽然双--只是bash语法糖来停止处理命令行标志。此外,-b cookies.txt-c cookies.txt标记处理Cookie,-b发送Cookie,-c在本地存储Cookie。

手册中有更多examples of authentication种方法。

答案 8 :(得分:4)

非常简单,请执行以下操作:

curl -X GET/POST/PUT <URL> -u username:password

答案 9 :(得分:3)

如果您使用的是具有Gnome密钥环应用程序的系统,则避免直接泄露密码的解决方案是使用{{3}}从密钥环中提取密码:

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

答案 10 :(得分:3)

其他答案建议netrc根据我的阅读结果指定用户名和密码,我同意。以下是一些语法详细信息:

https://ec.haxx.se/usingcurl-netrc.html

与其他答案一样,我想强调一下,在此问题上需要注意安全性。

尽管我不是专家,但我发现这些链接很有见地:

https://ec.haxx.se/cmdline-passwords.html

总结:

使用协议的加密版本(HTTPS与HTTP)(FTPS与FTP)可以帮助避免网络泄漏。

使用 netrc 可以帮助避免命令行泄漏。

要更进一步,似乎您也可以使用gpg加密netrc文件

https://brandur.org/fragments/gpg-curl

通过这种方式,您的凭据不会以纯文本的形式“静止”(存储)。

答案 11 :(得分:3)

通常将CURL命令称为

curl https://example.com\?param\=ParamValue -u USERNAME:PASSWORD

如果您没有任何密码,或者想跳过命令提示符以要求输入简单密码,请将密码部分留空。

curl https://example.com\?param\=ParamValue -u USERNAME:

答案 12 :(得分:2)

您可以使用像

这样的命令
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

答案 13 :(得分:2)

我在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' ...就可以了。

如果评论或编辑可以解释原因,我会很高兴!

答案 14 :(得分:1)

在某些API中,它可能无法正常工作(例如rabbitmq)。

还有其他选择:

curl http://username:password@example.com

curl http://admin:123456@example.com

答案 15 :(得分:0)

将凭据传递给curl的最安全方法是提示插入凭据。如先前建议的那样传递用户名时,会发生这种情况(-u USERNAME)。

但是如果您不能以这种方式传递用户名怎么办? 例如,用户名可能需要是url的一部分,而只有密码是json负载的一部分。

tl;博士: 在这种情况下,这是安全使用curl的方法:

read -p "Username: " U; read -sp "Password: " P; curl --request POST -d "{\"password\":\"${P}\"}" https://example.com/login/${U}; unset P U

read将从命令行提示输入用户名和密码,并将提交的值存储在两个变量中,这些变量可以在后续命令中引用,并且最终未设置。

我将详细说明为什么其他解决方案不理想。

为什么环境变量不安全

  1. 由于环境对于进程是隐式可用的,因此无法跟踪环境变量内容的访问和暴露模式(ps -eww)
  2. 应用程序通常会抓住整个环境并记录下来以进行调试或监视(有时在磁盘上以纯文本格式记录日志文件,尤其是在应用程序崩溃后)
  3. 环境变量向下传递到子进程(因此违反了最小特权原则)
  4. 维护它们是一个问题:新工程师不知道他们在那里,也不了解周围的需求-例如,不要将它们传递给子流程-因为它们没有得到执行或记录。

为什么直接在命令行上将其键入命令不安全 因为您的机密最终将被运行ps -aux的任何其他用户看到,因为它列出了为每个当前正在运行的进程提交的命令。 同样是因为您的密钥随后出现在bash历史记录中(一旦shell终止)。

为什么将其包含在本地文件中不安全 对文件的严格POSIX访问限制可以减轻这种情况下的风险。但是,它仍然是文件系统上的文件,静态时未加密。

答案 16 :(得分:0)

这比OP要求的要多得多,但是由于这是将密码安全地传递到curl的最佳结果,因此我在这里为那些来此进行搜索的其他人添加了这些解决方案。


注意:-s命令的read arg不是POSIX,因此并非在所有地方都可用,因此下面将不再使用。我们将改用stty -echostty echo

注意:如果在函数中,则下面的所有bash变量都可以声明为局部变量,而不是取消设置。

注意:perl在我尝试过的所有系统上都很普遍,因为它是许多事情的依赖项,而rubypython则不是,所以使用{{ 1}}。如果可以保证在perl / ruby上执行此操作,则可以将python命令替换为其等效内容。

注意:在perl 3.2.57中于macOS 10.14.4进行了测试。其他外壳/安装可能需要一些小的翻译。


安全地提示用户输入(可重复使用的)密码以进行卷曲。如果需要多次调用curl,则特别有用。

对于现代贝壳,bash是内置的(通过echo检查):

which echo

对于较旧的Shell,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 类似于echo(在进程列表中可以看到其回声):
此版本无法重用密码,请向下查看。

/bin/echo



如果您碰巧需要将密码临时存储到文件中,请在清除密码之前将其重用于多个命令(例如,因为您正在使用代码重用功能,并且不想重复代码,并且无法通过echo传递值)。 (是的,在这种形式下它们不是在不同的库中具有功能,因此有些许作弊;我试图将它们减少到显示它所需的最少代码。)

当echo是内置的时(由于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

当回声类似于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 时:

/bin/echo