【问题标题】:Basic HTTP and Bearer Token Authentication基本 HTTP 和承载令牌身份验证
【发布时间】:2014-04-09 09:56:27
【问题描述】:

我目前正在为开发环境开发一个受 HTTP-Basic 保护的 REST-API。由于真正的身份验证是通过令牌完成的,我仍在尝试弄清楚如何发送两个授权标头。

这个我试过了:

curl -i http://dev.myapp.com/api/users \
  -H "Authorization: Basic Ym9zY236Ym9zY28=" \
  -H "Authorization: Bearer mytoken123"

例如,我可以为我的 IP 禁用 HTTP 身份验证,但由于我通常在具有动态 IP 的不同环境中工作,这不是一个好的解决方案。所以我错过了什么吗?

【问题讨论】:

  • 我需要通过 HTTP Basic 进行身份验证,因为开发服务器受到它的保护,并且我需要基于令牌的 API 身份验证。但是当我使用 curl 来测试 api 时,我需要一种方法来发送两个身份验证标头。所以第一个(基本)传递 HTTP Basic 和第二个(令牌)对我的应用程序进行身份验证。是的,这是我自己的创作。
  • 你有想过这个吗?我正在添加赏金
  • 你好亚当,很遗憾没有。我现在通过将令牌的授权标头更改为不是标准标头的“x-auth”来更改身份验证的工作方式。
  • 我的 nginx 服务器甚至不接受 2 个授权标头。它返回一个400 Bad request。傻。
  • 为您的 API 令牌使用自定义标头有什么问题?我不明白为什么这里的人已经“废弃”了使用 HTTP Basic Auth 来防止他们的开发/登台服务器被窥探。

标签: rest curl basic-authentication access-token restful-authentication


【解决方案1】:

试试这个在 url 推送基本身份验证:

curl -i http://username:password@dev.myapp.com/api/users -H "Authorization: Bearer mytoken123"
               ^^^^^^^^^^^^^^^^^^

如果上面的一个不起作用,那么你与它无关。所以尝试以下替代方案。

您可以使用其他名称传递令牌。因为您正在处理来自您的应用程序的授权。因此,您可以轻松地将这种灵活性用于此特殊目的。

curl -i http://dev.myapp.com/api/users \
  -H "Authorization: Basic Ym9zY236Ym9zY28=" \
  -H "Application-Authorization: mytoken123"

请注意,我已将标题更改为 Application-Authorization。因此,从您的应用程序中捕获该标头下的令牌并处理您需要做的事情。

您可以做的另一件事是,通过POST 参数传递token,并从服务器端获取参数的值。例如使用 curl post 参数传递令牌:

-d "auth-token=mytoken123"

【讨论】:

  • 您好 Sabuj,问题不在于您传递用户名和密码的方式,而是多个授权标头不起作用。查看规格 (ietf.org/rfc/rfc2617.txt) 我可以看到这应该是可能的。但也如前所述““用户代理必须选择使用它理解的最强身份验证方案的挑战之一,并根据该挑战向用户请求凭据。”所以就像我在 2 天前写的那样,我需要通过标记为非标准标头,当您处理非标准架构时,这绝对没问题。
  • @Azngeek Curl 在您执行任务时会发送两个授权标头。您需要从服务器端处理它。只需使用 -v 参数运行带有两个标头的 curl 命令。您会发现它在请求标头处发送Authorization: Basic Ym9zY236Ym9zY28=, Authorization: Bearer mytoken123。从您的服务器端,如果您检查,您会发现您有这样的授权标头Authorization: Basic Ym9zY236Ym9zY28=, Bearer mytoken123,用逗号分隔。所以,我虽然我应该建议你替代。
【解决方案2】:

标准 (https://www.rfc-editor.org/rfc/rfc6750) 说你可以使用:

  • Form-Encoded Body 参数:授权:Bearer mytoken123
  • URI 查询参数:access_token=mytoken123

因此可以通过 URI 传递多个 Bearer Token,但不鼓励这样做(参见标准中的第 5 节)。

【讨论】:

    【解决方案3】:

    如果您在两者之间使用反向代理(例如 nginx),则可以定义自定义令牌,例如 X-API-Token

    在 nginx 中,您可以将上游代理(您的其余 api)重写为只是身份验证:

    proxy_set_header Authorization $http_x_api_token;
    

    ... 而 nginx 可以使用原始的 Authorization 标头来检查 HTTP AUth。

    【讨论】:

      【解决方案4】:

      我遇到了类似的问题 - 在设备上验证设备和用户。我使用了Cookie 标头和Authorization: Bearer... 标头。一个标头对设备进行身份验证,另一个标头对用户进行身份验证。我使用了Cookie 标头,因为这些通常用于身份验证。

      【讨论】:

      • 不清楚为什么投反对票。我在寻找相关问题的答案时遇到了这个问题 - 这就是我解决它的方法。 Cookie 标头已经经常用于身份验证。
      • 我认为某些人的问题是他们像我一样不知道您作为 cookie 发送的内容 - 与标头相同还是只是令牌或其他任何内容?
      【解决方案5】:

      curl --anyauth

      告诉 curl 自己找出身份验证方法,并使用 远程站点声称支持的最安全的一种。这是由 首先做一个请求并检查响应头,因此 可能会导致额外的网络往返。这是使用 而不是设置特定的身份验证方法,您可以 使用 --basic、--digest、--ntlm 和 --协商。

      【讨论】:

        【解决方案6】:

        使用 nginx,您可以像这样发送两个令牌(即使它违反标准):

        Authorization: Basic basic-token,Bearer bearer-token
        

        只要基本令牌在前就可以工作 - nginx 成功地将其转发到应用程序服务器。

        然后您需要确保您的应用程序可以正确地从上述字符串中提取 Bearer。

        【讨论】:

          【解决方案7】:

          还有另一种在开发服务器上测试 API 的解决方案。

          • 设置HTTP Basic Authentication 仅用于网络路由
          • 让所有 API 路由免于身份验证

          nginxLaravel 的 Web 服务器配置如下:

              location /api {
                  try_files $uri $uri/ /index.php?$query_string;
              }
          
              location / {
                  try_files $uri $uri/ /index.php?$query_string;
          
                  auth_basic "Enter password";
                  auth_basic_user_file /path/to/.htpasswd;
              }
          

          Authorization: Bearer 将保护开发服务器免受网络爬虫和其他不受欢迎的访问者的攻击。

          【讨论】:

            猜你喜欢
            • 2014-12-17
            • 1970-01-01
            • 1970-01-01
            • 2011-03-18
            • 1970-01-01
            • 2021-01-25
            • 2015-12-25
            • 1970-01-01
            • 2022-01-23
            相关资源
            最近更新 更多