【问题标题】:How to send a correct authorization header for basic authentication如何为基本身份验证发送正确的授权标头
【发布时间】:2013-08-18 08:17:53
【问题描述】:

我正在尝试从我的 API 发布数据,但我无法通过基本身份验证。

我试试:

$.ajax({
  type: 'POST',
  url: http://theappurl.com/api/v1/method/,
  data: {},
  crossDomain: true,
  beforeSend: function(xhr) {
    xhr.setRequestHeader('Authorization', 'Basic [REDACTED]');
  }
});

我的服务器配置响应是:

response["Access-Control-Allow-Origin"] = "*"
response["Access-Control-Allow-Methods"] = "POST"
response["Access-Control-Max-Age"] = "1000"
response["Access-Control-Allow-Headers"] = "*"

我得到的标题是:

请求标头

OPTIONS /api/v1/token-auth/ HTTP/1.1
Host: theappurl.com
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://127.0.0.1:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.63 Safari/537.31
Access-Control-Request-Headers: origin, authorization, content-type
Accept: */*
Referer: http://127.0.0.1:8080/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: es,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

响应标头

HTTP/1.1 401 Unauthorized
Server: nginx/1.1.19
Date: Fri, 16 Aug 2013 01:29:21 GMT
Content-Type: text/html
Content-Length: 597
Connection: keep-alive
WWW-Authenticate: Basic realm="Restricted"

我猜服务器配置不错,因为我可以从 Advanced REST Client(Chrome 扩展)访问 API

有什么建议吗?

PD: 我从高级 REST 客户端获得的标头是:

    User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.63 Safari/537.31
    Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
    Authorization: Basic [REDACTED]
    Content-Type: application/x-www-form-urlencoded 
    Accept: */*
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: es,en;q=0.8
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

    Server: nginx/1.1.19 
    Date: Fri, 16 Aug 2013 01:07:18 GMT 
    Content-Type: application/json; charset=utf-8 
    Transfer-Encoding: chunked 
    Connection: keep-alive
    Vary: Accept, Cookie 
    Allow: POST, OPTIONS 
    X-Robots-Tag: noindex

发送OPTION方法

【问题讨论】:

  • 我意识到这篇文章早已死去,但我只是想指出,以防您不知道通过发布您的 Authorization: 标头,您实际上已经清楚地发布了您的密码。那里的乱码字符串只是您的用户名:密码的base64编码,因此每个人都可以看到您的密码。希望您意识到这一点并在这里使用了一个虚拟密码:)
  • 这适用于 ssrs 报告服务器 2017。它隐藏了 URL 中的密码和用户名。
  • @Lexelby:用户名是“用户”,密码是西班牙语的“和密码”。所以我猜这些不是真正的凭据。

标签: jquery ajax django api cross-domain


【解决方案1】:

您可以在 URL 中包含用户名和密码:

http://user:passwd@www.server.com/index.html

查看此网址了解更多信息

HTTP Basic Authentication credentials passed in URL and encryption

当然,您需要用户名密码,而不是'Basic hashstring

希望这会有所帮助...

【讨论】:

  • 该解决方案不适用于 Android 的本机浏览器 (Pre KitKat)。用户名/登录表单仍会为您的用户弹出,所以要小心。
  • 此方法将用户名和密码暴露给任何在网络或设备上监听的人...
  • @Adam 哈希字符串也不安全
  • 这根本不能回答问题。将其作为 url 传递不是标题。
  • 拒绝投票原因:developer.mozilla.org/en-US/docs/Web/HTTP/Authentication。文末提到The use of these URLs is deprecated
【解决方案2】:

根据 https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decodinghttp://en.wikipedia.org/wiki/Basic_access_authentication ,这里是如何使用标头进行基本身份验证,而不是将用户名和密码放在 URL 中。请注意,这仍然不会对有权访问网络或此 JS 代码的任何人(例如,在浏览器中执行它的用户)隐藏用户名或密码:

$.ajax({
  type: 'POST',
  url: http://theappurl.com/api/v1/method/,
  data: {},
  crossDomain: true,
  beforeSend: function(xhr) {
    xhr.setRequestHeader('Authorization', 'Basic ' + btoa(unescape(encodeURIComponent(YOUR_USERNAME + ':' + YOUR_PASSWORD))))
  }
});

【讨论】:

  • 注意:要在 IE6、7、8、9 中使用此功能,需要一个 window.btoa polyfill,例如 Base64.js。根据 ECMAScript v3,不推荐使用 unescape。
  • @Techbrunch 你误会了,seanp2k 的例子效果很好,它使用一个众所周知的技巧将 Unicode 字符解码为 ASCII,它实际上使用了 (un)escape 不支持 Unicode 的事实,但是( dec)encodeURIComponent 确实..
【解决方案3】:

不需要在 URL 中使用用户名和密码

你可以试试这个

byte[] encodedBytes = Base64.encodeBase64("user:passwd".getBytes());

String USER_PASS = new String(encodedBytes);

HttpUriRequest request = RequestBuilder.get(url).addHeader("Authorization", USER_PASS).build();

【讨论】:

    【解决方案4】:

    NodeJS 答案:

    如果你想用 NodeJS 做这件事:使用 Authorization 标头创建一个 GET 到 JSON 端点并返回一个 Promise

    第一

    npm install --save request request-promise
    

    (see on npm) 然后在你的.js 文件中:

    var requestPromise = require('request-promise');
    
    var user = 'user';
    var password = 'password';
    
    var base64encodedData = Buffer.from(user + ':' + password).toString('base64');
    
    requestPromise.get({
      uri: 'https://example.org/whatever',
      headers: {
        'Authorization': 'Basic ' + base64encodedData
      },
      json: true
    })
    .then(function ok(jsonData) {
      console.dir(jsonData);
    })
    .catch(function fail(error) {
      // handle error
    });
    

    【讨论】:

    • 谢谢你在我使用“fetch”的反应应用程序中工作
    • 谢谢你!也与 fetch 一起工作
    【解决方案5】:

    如果你在浏览器环境中也可以使用btoa

    btoa 是一个将字符串作为参数并生成 Base64 编码的 ASCII 字符串的函数。由97% of browsers支持。

    例子:

    > "Basic " + btoa("billy"+":"+"secretpassword")
    < "Basic YmlsbHk6c2VjcmV0cGFzc3dvcmQ="
    

    然后您可以将Basic YmlsbHk6c2VjcmV0cGFzc3dvcmQ= 添加到authorization 标头。

    请注意,有关 HTTP BASIC 身份验证的常见警告适用,最重要的是,如果您不通过 h​​ttps 发送流量,则被窃听者可以简单地解码 Base64 编码的字符串,从而获得您的密码。

    This security.stackexchange.com 回答很好地概述了一些缺点。

    【讨论】:

      【解决方案6】:

      PHP - 卷曲

      $username = 'myusername';
      $password = 'mypassword';
      ...
      curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
      ...
      

      PHP - WordPress 中的 POST

      $username = 'myusername';
      $password = 'mypassword';
      ...
      wp_remote_post('https://...some...api...endpoint...', array(
        'headers' => array(
          'Authorization' => 'Basic ' . base64_encode("$username:$password")
        )
      ));
      ...
      

      【讨论】:

        猜你喜欢
        • 2015-05-05
        • 2012-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-10
        • 2017-04-25
        • 2019-12-18
        相关资源
        最近更新 更多