Cómo enviar un encabezado de autorización correcto para la autenticación básica

100

Estoy intentando POSTAR datos desde mi API pero no puedo pasar la autenticación básica.

Lo intento:

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

La respuesta de configuración de mi servidor es:

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

Los encabezados que obtengo son:

Solicitar encabezados

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

Encabezado de respuesta

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"

Supongo que la configuración del servidor es buena porque puedo acceder a la API desde el cliente REST avanzado (extensión de Chrome)

¿Alguna sugerencia?

PD: El encabezado que obtengo del cliente REST avanzado es:

    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

y

    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

método de envío de OPCIÓN

individuo7
fuente
19
Me doy cuenta de que esta publicación está muerta hace mucho tiempo, pero solo quiero señalar en caso de que no sepa que al publicar su autorización: encabezado, esencialmente ha publicado su contraseña en claro. La cadena de galimatías allí es solo la codificación base64 de su nombre de usuario: contraseña, para que todos puedan ver su contraseña. Con suerte, se dio cuenta de esto y utilizó una contraseña ficticia aquí :)
Lexelby
Esto funciona bien con el servidor de informes SSR 2017. Oculta la contraseña y el nombre de usuario en la URL.
Clark Vera
@Lexelby: El nombre de usuario es "el usuario" y la contraseña es "y la contraseña" en español. Así que supongo que estas no son credenciales reales.
pdr

Respuestas:

48

Puede incluir el usuario y la contraseña como parte de la URL:

http://user:[email protected]/index.html

ver esta URL, para más

Credenciales de autenticación básica HTTP pasadas en URL y cifrado

por supuesto, necesitará la contraseña del nombre de usuario, no lo es 'Basic hashstring.

espero que esto ayude...

Dru
fuente
6
Esa solución no funcionará para el navegador nativo de Android (Pre KitKat). El formulario de nombre de usuario / inicio de sesión seguirá apareciendo para su usuario, así que tenga cuidado.
Sterling Bourne
58
Este método expone el nombre de usuario y la contraseña a cualquiera que esté escuchando en la red o dispositivos ...
Adam
5
@Adam hash string tampoco es seguro
Mustafa
38
Esto no responde la pregunta en absoluto. Pasarlo como una URL no es un encabezado.
jemiloii
5
Motivo del voto negativo: developer.mozilla.org/en-US/docs/Web/HTTP/Authentication . Hacia el final del artículo, menciona queThe use of these URLs is deprecated
anurupr
70

Según https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding y http://en.wikipedia.org/wiki/Basic_access_authentication , aquí se explica cómo realizar la autenticación básica con un encabezado en su lugar de poner el nombre de usuario y la contraseña en la URL. Tenga en cuenta que esto todavía no oculta el nombre de usuario o la contraseña de cualquier persona con acceso a la red o este código JS (por ejemplo, un usuario que lo ejecuta en un navegador):

$.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))))
  }
});
seanp2k
fuente
1
Nota: Se requerirá un polyfill window.btoa como Base64.js para que esta característica funcione en IE6,7,8,9. Además, unescape está en desuso según ECMAScript v3.
nulo
@Techbrunch estás equivocado, el ejemplo de seanp2k funciona muy bien, usa un truco muy conocido para decodificar caracteres Unicode a ASCII, en realidad usa el hecho de que (un) escape no es compatible con Unicode, pero (dec) encodeURIComponent sí lo hace ..
40

Respuesta de NodeJS:

En caso de que quisiera hacerlo con NodeJS: cree un punto final GET a JSON con Authorizationencabezado y obtenga unPromise devolución:

primero

npm install --save request request-promise

( ver en npm ) y luego en su .jsarchivo:

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
});
jakub.g
fuente
1
Gracias, me salvaste el día :)
Sparw
Gracias, esto funcionó en mi aplicación de reacción que usó "fetch"
MohsenFM
13

Si está en un entorno de navegador, también puede usar btoa .

btoaes una función que toma una cadena como argumento y produce una cadena ASCII codificada en Base64. Es compatible con el 97% de los navegadores. .

Ejemplo:

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

Luego puede agregar Basic YmlsbHk6c2VjcmV0cGFzc3dvcmQ=al authorizationencabezado.

Tenga en cuenta que se aplican las advertencias habituales sobre la autenticación HTTP BASIC, y lo más importante es que si no envía su tráfico a través de https, un escuchado puede simplemente decodificar la cadena codificada en Base64 y obtener así su contraseña.

Esta respuesta security.stackexchange.com ofrece una buena descripción general de algunas de las desventajas.

Fernandohur
fuente
3

no es necesario utilizar el usuario y la contraseña como parte de la URL

puedes probar esto

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

String USER_PASS = new String(encodedBytes);

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