将标准输入管道连接到 cURL 标头

Posted

技术标签:

【中文标题】将标准输入管道连接到 cURL 标头【英文标题】:Piping stdin to a cURL header 【发布时间】:2022-01-08 05:51:16 【问题描述】:

我正在尝试从 Keycloak 端点读取获取身份验证令牌并使用它来访问另一个资源。获取令牌不是问题,但在另一个请求的标头中传递它是一个不可能的壮举,至少在一个命令中:

curl \
    -X POST \
    -d 'client_id=app' \
    -d 'username=username' \
    -d 'password=password' \
    -d 'grant_type=password' \
    -d "client_secret=$APP_SECRET" \
    'http://localhost:9000/auth/realms/realm/protocol/openid-connect/token' \
| \
jq -r '.access_token' \
| \
curl \
    -X GET \
    -H "Accept: application/json" \
    -H "Authorization: Bearer @-" \ # <- read header value from stdin
    -u "username:password" \
    "http://localhost:8080/app/api/"

实现这一目标的替代方法是什么?

【问题讨论】:

这可能会有所帮助:echo def | echo "abc$(&lt;/dev/stdin)ghi" @Cyrus 有点:回声 123 | echo "abc $(/stdin) def" zsh: 读取 /dev/stdin 时出错:输入/输出错误 abc def 将标签“bash”替换为“zsh”。希望对您有所帮助。 为什么不简单地分两步完成呢?提取令牌,存储在变量中并在下一个 curl? 中重新使用它 因为我不擅长 shell 脚本。 :) 【参考方案1】:

与其创建一个复杂的命令,不如将它拆分成2个动作:

    Save the token to a variable Pass the variable to the header

# Get token
token=$(curl \
    -X POST \
    -d 'client_id=app' \
    -d 'username=username' \
    -d 'password=password' \
    -d 'grant_type=password' \
    -d "client_secret=$APP_SECRET" \
    'http://localhost:9000/auth/realms/realm/protocol/openid-connect/token' \
| jq -r '.access_token')

# Send request
curl \
    -X GET \
    -H "Accept: application/json" \
    -H "Authorization: Bearer $token" \
    -u "username:password" \
    "http://localhost:8080/app/api/"

【讨论】:

【参考方案2】:

另一个答案提供了更好的解决方案,但这篇文章回答了所提出的字面问题。

您可以使用以下内容:

"Authorization: Bearer $( cat )"

演示:

$ echo foo | printf "%s\n" "Authorization: Bearer $( cat )"
Authorization: Bearer foo

事实上,您可以将整个令牌获取代码放在$() 中。

curl                              \
    -X GET                        \
    -H "Accept: application/json" \
    -H "Authorization: Bearer $(
        curl                               \
            -X POST                        \
            -d "client_id=app"             \
            -d "username=username"         \
            -d "password=password"         \
            -d "grant_type=password"       \
            -d "client_secret=$APP_SECRET" \
            "http://localhost:9000/auth/realms/realm/protocol/openid-connect/token" \
        | jq -r .access_token
    )"                            \
    -u "username:password"        \
    "http://localhost:8080/app/api/"

演示:

$ printf "%s\n" "Authorization: Bearer $( echo foo )"
Authorization: Bearer foo

再次,我认为这些不如@0stone0 提供的更清晰的解决方案。我将它们发布用于教育目的。

【讨论】:

以上是关于将标准输入管道连接到 cURL 标头的主要内容,如果未能解决你的问题,请参考以下文章

golang 将套接字附加到标准输入/标准输出

Linux管道(Pipes)

curl 日志分析

curl 日志分析

Linux 重定向与管道符

执行脚本2