การพิสูจน์ตัวตนขั้นพื้นฐานด้วยการดึงข้อมูล?


122

ฉันต้องการเขียนการรับรองความถูกต้องพื้นฐานง่ายๆด้วยการดึงข้อมูล แต่ฉันได้รับข้อผิดพลาด 401 อยู่เรื่อย ๆ จะดีมากถ้ามีคนบอกรหัสว่ามีอะไรผิดปกติ:

let base64 = require('base-64');

let url = 'http://eu.httpbin.org/basic-auth/user/passwd';
let username = 'user';
let password = 'passwd';

let headers = new Headers();

//headers.append('Content-Type', 'text/json');
headers.append('Authorization', 'Basic' + base64.encode(username + ":" + password));

fetch(url, {method:'GET',
        headers: headers,
        //credentials: 'user:passwd'
       })
.then(response => response.json())
.then(json => console.log(json));
//.done();

function parseJSON(response) {
return response.json()
}

คำตอบ:


117

คุณไม่มีช่องว่างระหว่างBasicชื่อผู้ใช้และรหัสผ่านที่เข้ารหัส

headers.set('Authorization', 'Basic ' + base64.encode(username + ":" + password));

8
ไม่ได้สร้าง atob และ btoa ตามข้อกำหนดของ Javascript หรือไม่
Martin

6
ทั้ง 2 ฟังก์ชั่นมีให้ใช้งานในเบราว์เซอร์หลัก ๆ ทั้งหมด แต่ฉันไม่คิดว่ามันจะครอบคลุมโดยข้อกำหนด ES ใด ๆ โดยเฉพาะอย่างยิ่งคุณจะไม่พบใน node.js github.com/nodejs/node/issues/3462
Lukasz Wiktor

โปรดทราบว่าสิ่งนี้ไม่ได้สร้างเซสชันสำหรับเบราว์เซอร์ คุณสามารถใช้ XHR เพื่อสร้างเซสชันและหลีกเลี่ยงการเข้ารหัส base64 ดู: stackoverflow.com/a/58627805/333296
Nux

Uncaught ReferenceError: base64 ไม่ได้กำหนดไว้
Sveen

@Sveen base64หมายถึงไลบรารีที่นำเข้าในโพสต์ต้นฉบับ ไม่ใช่แบบโกลบอลในตัว แต่เป็นไลบรารีที่อิมพอร์ตในโมดูล CJS
oligofren

90

โซลูชันที่ไม่มีการพึ่งพา

ปม

headers.set('Authorization', 'Basic ' + Buffer.from(username + ":" + password).toString('base64'));

เบราว์เซอร์

headers.set('Authorization', 'Basic ' + btoa(username + ":" + password));

5
ในเบราว์เซอร์คุณสามารถใช้window.btoa(username + ':' + password); developer.mozilla.org/en-US/docs/Web/API/WindowBase64/…
Andreas

1
เพื่อรองรับอักขระพิเศษบางอย่างเช่น window.btoa(unescape(encodeURIComponent(string)));ควรทำงานคุณสามารถอ่านเพิ่มเติมได้ที่นี่: developer.mozilla.org/en-US/docs/Web/API/WindowBase64/…
Andreas

นอกจากนี้ยังขึ้นอยู่กับเวอร์ชันของโหนดของคุณที่fetchไม่มีอยู่
dovidweisz

18

คุณยังสามารถใช้btoaแทน base64.encode () ได้

headers.set('Authorization', 'Basic ' + btoa(username + ":" + password));

1. เฉพาะในเบราว์เซอร์ 2. ที่มีอักขระ ascii เท่านั้น
Lukas Liesis

7

หากคุณมีเซิร์ฟเวอร์แบ็กเอนด์ที่ขอข้อมูลรับรองการตรวจสอบสิทธิ์ขั้นพื้นฐานก่อนแอปแสดงว่าเพียงพอแล้วระบบจะนำกลับมาใช้:

fetch(url, {
  credentials: 'include',
}).then(...);

4

ตัวอย่างง่ายๆสำหรับการคัดลอกวางลงในคอนโซล Chrome:

fetch('https://example.com/path', {method:'GET', 
headers: {'Authorization': 'Basic ' + btoa('login:password')}})
.then(response => response.json())
.then(json => console.log(json));

2

ผู้ใช้ NODE (REACT, EXPRESS) ทำตามขั้นตอนเหล่านี้

  1. npm install base-64 --save
  2. import { encode } from "base-64";
  3.  const response = await fetch(URL, {
      method: 'post',
      headers: new Headers({
        'Authorization': 'Basic ' + encode(username + ":" + password),
        'Content-Type': 'application/json'
      }),
      body: JSON.stringify({
        "PassengerMobile": "xxxxxxxxxxxx",
        "Password": "xxxxxxx"
      })
    });
    const posts = await response.json();
  4. อย่าลืมกำหนดฟังก์ชันทั้งหมดนี้เป็น async


1

ฉันจะแชร์รหัสที่มีเนื้อหาคำขอข้อมูลในรูปแบบ Basic Auth Header

let username = 'test-name';
let password = 'EbQZB37gbS2yEsfs';
let formdata = new FormData();
let headers = new Headers();


formdata.append('grant_type','password');
formdata.append('username','testname');
formdata.append('password','qawsedrf');

headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));
fetch('https://www.example.com/token.php', {
 method: 'POST',
 headers: headers,
 body: formdata
}).then((response) => response.json())
.then((responseJson) => {
 console.log(responseJson);

 this.setState({
    data: responseJson
 })
  })
   .catch((error) => {
 console.error(error);
   });

0

สิ่งนี้ไม่เกี่ยวข้องโดยตรงกับปัญหาเริ่มต้น แต่อาจช่วยใครบางคนได้

ฉันประสบปัญหาเดียวกันเมื่อพยายามส่งคำขอที่คล้ายกันโดยใช้บัญชีโดเมน ปัญหาของฉันจึงไม่ได้อยู่ในอักขระที่ไม่ได้หลบหนีในชื่อล็อกอิน

ตัวอย่างที่ไม่ดี:

'ABC\username'

ตัวอย่างที่ดี:

'ABC\\username'

นี่เป็นเพียงเพราะคุณต้องการหลีกเลี่ยงอักขระหนีสตริง js เองอย่างไรก็ตามสิ่งนี้ไม่เกี่ยวข้องกับการตรวจสอบสิทธิ์ขั้นพื้นฐาน
qoomon

@qoomon ถูกต้อง. นั่นเป็นเหตุผลที่ฉันกล่าวว่ามันไม่เกี่ยวข้องโดยตรง แต่อาจเป็นประโยชน์
DJ-Glock
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.