301

I want to write a simple basic authentication with fetch, but I keep getting a 401 error. It would be awesome if someone tells me what's wrong with the code:

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();
0

9 Answers 9

323

A solution without dependencies.

Node

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

Browser

headers.set('Authorization', 'Basic ' + btoa(username + ":" + password));
Sign up to request clarification or add additional context in comments.

3 Comments

In a browser you can use window.btoa(username + ':' + password); developer.mozilla.org/en-US/docs/Web/API/WindowBase64/…
to support special characters something like window.btoa(unescape(encodeURIComponent(string))); should do the job, you can read more about this here: developer.mozilla.org/en-US/docs/Web/API/WindowBase64/…
Also depending on your version of node fetch doesn't exist there.
232

You are missing a space between Basic and the encoded username and password.

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

6 Comments

Isnt atob and btoa built in to the Javascript specification?
The 2 functions are available in all major browsers, but I don't think they are covered by any ES specification. In particular, you won't find them in node.js github.com/nodejs/node/issues/3462
Note that this does NOT establish a session for the browser. You can use XHR to both establish a session and avoid base64 encoding. See: stackoverflow.com/a/58627805/333296
@Sveen base64 refers to the library imported in the original post. It is not a built-in global, but a library that was imported in the CJS module.
When using node, you have to use Buffer and specify utf8 const headers = { Authorization: `Basic ${Buffer.from("user:pass", "utf-8").toString("base64")}` };
|
50

In pure JavaScript you can also use btoa instead of base64.encode():

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

Note that this will only work with ASCII characters.

If you have to handle different encodings, see the linked btoa documentation.

2 Comments

1. only in browsers 2. only with ascii characters.
A note on voting: this answer mentioned btoa half a year before the equivalent snippet showed up in an edit of the most voted answer by Coomon.
46

A simple example for copy-pasting into Chrome console:

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

or with await:

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

Comments

18

If you have a backend server asking for the Basic Auth credentials before the app then this is sufficient, it will re-use that then:

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

Comments

15

NODE USERS (REACT,EXPRESS) FOLLOW THESE STEPS

  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. Don't forget to define this whole function as async

Comments

4

get request with authorization for React Native Mobile application, i have spent more time searching for these lines inside fetch

 var base64 = require("base-64"); // install it before use from npm i base-64

 const uname = "some username goes here";
 const pword = "some password goes here";

const getMovies = async () => {
   try {
     const response = await fetch(
       "API URL goes here",
       {
         headers: {
           Authorization: "Basic " + base64.encode(uname + ":" + pword),
         },
       }
     );

     data = await response.json();
     setData(data);

     console.log(data);
     // console.log(data.name);
     return data;
   } catch (error) {
     console.error(error);
   } finally {
     setLoading(false);
   }
 };

 useEffect(() => {
   getMovies();
 }, []);


// other code 

// inside return
  <FlatList
           keyExtractor={(item) => item.id}
           data={data}
           renderItem={({ item }) => (
             <View style={styles.text_container}>
               <Text>{item.name}</Text>
               <Text>{item.images[0].name}</Text>
               <Text>{item.images[0].src}</Text>
             </View>
           )}
         />

Comments

3

I'll share a code which has Basic Auth Header form data request body,

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);
   });

Comments

1

This is not directly related to the initial issue, but probably will help somebody.

I faced same issue when was trying to send similar request using domain account. So mine issue was in not escaped character in login name.

Bad example:

'ABC\username'

Good example:

'ABC\\username'

2 Comments

This is just because you need to escape js string escape character itself, however this is not basic auth related.
@qoomon correct. That's why I mentioned that it is not directly related, but might be helpful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.