如何发送正确的授权标头以进行基本身份验证


99

我正在尝试从我的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"

我猜服务器配置不错,因为我可以从高级REST客户端(Chrome扩展程序)访问API

有什么建议?

PD:我从Advanced 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方法


19
我知道这篇文章已经死了,但我只是想指出一下,以防您不知道通过发布Authorization:标头实际上已经将密码清楚地发布了。乱码字符串只不过是您的用户名:密码的base64编码,因此每个人都可以看到您的密码。希望您意识到了这一点,并在此处使用了虚拟密码:)
Lexelby 2014年

这在ssrs报表服务器2017中可以正常工作。它在URL中隐藏了密码和用户名。
Clark Vera

@Lexelby:用户名是“用户”,密码是“ and the password”(西班牙语)。所以我猜这些不是真实的凭证。
pdr

Answers:


48

您可以将用户名和密码作为URL的一部分:

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

看到这个URL,更多

URL和加密中传递的HTTP基本身份验证凭据

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

希望这可以帮助...


6
该解决方案不适用于Android的本机浏览器(Pre KitKat)。用户名/登录表单仍会为您的用户弹出,因此请小心。
Sterling Bourne

58
此方法向在网络或设备上监听的任何人公开用户名和密码...
亚当

5
@Adam哈希字符串也不安全
Mustafa

38
这根本无法回答问题。将其作为url传递不是标头。
jemiloii,2015年

5
否决原因:developer.mozilla.org/zh-CN/docs/Web/HTTP/Authentication。在文章结尾处,它提到The use of these URLs is deprecated
anurupr

70

按照https://developer.mozilla.org/zh-CN/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))))
  }
});

1
注意:要使此功能在IE6、7、8、9中运行,需要使用诸如base64.js之类的window.btoa polyfill。此外,根据ECMAScript v3,不建议使用unescape。
空值

@Techbrunch你误会了,seanp2k的例子作品非常好,它采用了非常著名的把戏解码Unicode字符为ASCII,它实际上使用的事实,(联合国)越狱不支持Unicode,但(DEC)encodeURIComponent方法不..

40

NodeJS答案:

如果您想使用NodeJS进行此操作:使用Authorization标头进行GET至JSON端点并Promise返回:

第一

npm install --save request request-promise

请参阅npm),然后在您的.js文件中:

var requestPromise = require('request-promise');

var user = 'user';
var password = 'password';

var base64encodedData = new Buffer(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
});

1
谢谢,您保存了我的一天:)
Sparw 18'Jul

谢谢您,这在我使用“ fetch”的react应用程序中
起作用

13

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

btoa是一个将字符串作为参数并生成Base64编码的ASCII字符串的函数。97%的浏览器都支持它。

例:

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

然后,您可以添加Basic YmlsbHk6c2VjcmV0cGFzc3dvcmQ=authorization标题。

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

这个security.stackexchange.com答案很好地概述了一些缺点。


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();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.