วิธีส่งส่วนหัวการอนุญาตที่ถูกต้องสำหรับการตรวจสอบสิทธิ์ขั้นพื้นฐาน


101

ฉันกำลังพยายามโพสต์ข้อมูลจาก 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"

ฉันเดาว่าการกำหนดค่าเซิร์ฟเวอร์นั้นดีเพราะฉันสามารถเข้าถึง API จากไคลเอนต์ REST ขั้นสูง (ส่วนขยายของ Chrome)

ข้อเสนอแนะใด ๆ ?

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

ใช้งานได้ดีกับเซิร์ฟเวอร์รายงาน ssrs 2017 มันซ่อนรหัสผ่านและชื่อผู้ใช้ใน URL
Clark Vera

@Lexelby: ชื่อผู้ใช้คือ "ผู้ใช้" และรหัสผ่านคือ "และรหัสผ่าน" ในภาษาสเปน ฉันเดาว่านี่ไม่ใช่ข้อมูลรับรองจริง
pdr

คำตอบ:


48

คุณสามารถรวมผู้ใช้และรหัสผ่านเป็นส่วนหนึ่งของ URL:

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

ดู URL นี้สำหรับข้อมูลเพิ่มเติม

ข้อมูลประจำตัว HTTP Basic Authentication ที่ส่งผ่านใน URL และการเข้ารหัส

'Basic hashstringแน่นอนคุณจะต้องใช้รหัสผ่านชื่อผู้ใช้ก็ไม่ได้

หวังว่านี่จะช่วยได้ ...


6
โซลูชันดังกล่าวจะใช้ไม่ได้กับ Native Browser (Pre KitKat) ของ Android ชื่อผู้ใช้ / แบบฟอร์มเข้าสู่ระบบจะยังคงปรากฏขึ้นสำหรับผู้ใช้ของคุณดังนั้นโปรดใช้ความระมัดระวัง
Sterling Bourne

59
วิธีนี้จะเปิดเผยชื่อผู้ใช้และรหัสผ่านให้กับทุกคนที่ฟังบนเครือข่ายหรืออุปกรณ์ ...
อดัม

5
สตริงแฮชของ @Adam ก็ไม่ปลอดภัยเช่นกัน
มุสตาฟา

40
นี่ไม่ตอบคำถามเลย การส่งเป็น url ไม่ใช่ส่วนหัว
jemiloii

5
เหตุผล downvote: developer.mozilla.org/en-US/docs/Web/HTTP/Authentication ในตอนท้ายของบทความระบุว่าThe use of these URLs is deprecated
anurupr

72

ต่อhttps://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decodingและhttp://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
หมายเหตุ: ต้องใช้ window.btoa polyfill เช่น Base64.js เพื่อให้ฟีเจอร์นี้ทำงานใน IE6,7,8,9 นอกจากนี้ unescape ยังเลิกใช้ตาม ECMAScript v3
null

@Techbrunch คุณเข้าใจผิดตัวอย่างของ seanp2k ใช้งานได้ดีมากโดยใช้เคล็ดลับที่รู้จักกันดีในการถอดรหัสอักขระ Unicode เป็น ASCII โดยใช้ข้อเท็จจริงที่ว่า (un) escape ไม่รองรับ Unicode แต่ (dec) encodeURIComponent ..

43

คำตอบ NodeJS:

ในกรณีที่คุณต้องการทำกับ NodeJS: สร้างจุดสิ้นสุด GET to JSON พร้อมAuthorizationส่วนหัวและรับPromiseกลับ:

อันดับแรก

npm install --save request request-promise

( ดูใน 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
});

1
ขอบคุณคุณช่วยชีวิตฉันไว้ :)
Sparw

ขอบคุณที่ใช้งานได้ในแอปพลิเคชันการตอบสนองของฉันซึ่งใช้ "ดึงข้อมูล"
MohsenFM

13

หากคุณอยู่ในสภาพแวดล้อมของเบราว์เซอร์คุณสามารถใช้btoaได้เช่นกัน

btoaเป็นฟังก์ชันที่รับสตริงเป็นอาร์กิวเมนต์และสร้างสตริง ASCII ที่เข้ารหัส Base64 ได้รับการสนับสนุนโดยการ97% ของเบราว์เซอร์

ตัวอย่าง:

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

จากนั้นคุณสามารถเพิ่มลงBasic YmlsbHk6c2VjcmV0cGFzc3dvcmQ=ในauthorizationส่วนหัว

โปรดทราบว่าข้อควรระวังตามปกติเกี่ยวกับการตรวจสอบสิทธิ์พื้นฐาน HTTP ใช้ที่สำคัญที่สุดคือหากคุณไม่ส่งการเข้าชมผ่าน https ผู้ดักฟังสามารถถอดรหัสสตริงที่เข้ารหัส 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();
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.