フェッチによる基本認証?


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仕様に組み込まれていませんか?
マーティン

6
2つの関数はすべての主要なブラウザーで使用できますが、ES仕様でカバーされているとは思いません。特に、それらはnode.js github.com/nodejs/node/issues/3462で
Lukasz Wiktor

これはブラウザのセッションを確立しないことに注意してください。XHRを使用して、セッションの確立とbase64エンコーディングの回避の両方を行うことができます。参照:stackoverflow.com/a/58627805/333296
Nux

Uncaught ReferenceError:base64 is not defined
Sveen

@Sveen base64は、元の投稿でインポートされたライブラリを指します。これは組み込みグローバルではなく、CJSモジュールにインポートされたライブラリです。
オリゴフレン

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

1
特殊文字をサポートするためにwindow.btoa(unescape(encodeURIComponent(string)));必要なこと を行うには、developer.mozilla.org
en

また、ノードのバージョンによって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 USERS(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.