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();
A solution without dependencies.
Node
headers.set('Authorization', 'Basic ' + Buffer.from(username + ":" + password).toString('base64'));
Browser
headers.set('Authorization', 'Basic ' + btoa(username + ":" + password));
You are missing a space between Basic and the encoded username and password.
headers.set('Authorization', 'Basic ' + base64.encode(username + ":" + password));
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);
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.
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(...);
NODE USERS (REACT,EXPRESS) FOLLOW THESE STEPS
npm install base-64 --save
import { encode } from "base-64";
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();
Don't forget to define this whole function as async
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>
)}
/>
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);
});
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'
Related
I am trying to send a push to my phone through rest.
i tried:
async function SendPush(event)
{
event = event || window.event;
event.preventDefault();
var tokenID = "xxx"
let url = "https://fcm.googleapis.com/fcm/send";
let serverkey = 'yyy';
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Authorization', 'key=' + serverkey);
var dict = {
to : tokenID
};
let body = Object.entries(dict).map(([key, value]) =>
encodeURIComponent(`params[${key}]`) + '=' + encodeURIComponent(value)).join('&');
var res
await fetch(url, {
method: 'POST',
headers: {
Authorization: 'key=' + serverkey,
"Content-Type": "application/json"
},
body: body
}).then(response => response.json())
.then(data =>
{
//console.log(data);
res = data; // cannot return here. must await or something idk
});
console.log(res);
}
This object works on c# and in postman. I followed this convention:
URL:
https://fcm.googleapis.com/fcm/send
Header:
"Content-Type": "application/json",
"Authorization": "key=<Server_key>"
BODY:
{
"to": "<Device FCM token>",
"notification": {
"title": "Check this Mobile (title)",
"body": "Rich Notification testing (body)",
"mutable_content": true,
"sound": "Tri-tone"
},
"data": {
"url": "<url of media image>",
"dl": "<deeplink action on tap of notification>"
}
}
But I am getting:
JSON.parse: unexpected character at line 1 column 1 of the JSON data
Can you tell me, where my error is?
try
let body = JSON.stringify(dict)
instead of
let body = Object.entries(dict).map(([key, value]) =>
encodeURIComponent(`params[${key}]`) + '=' + encodeURIComponent(value)).join('&');
The body in fetch must match "Content-Type" header
I have written the following code to access the companies house api (https://developer.company-information.service.gov.uk/). I have googled and tried many things and I have no idea how to get data from this api using fetch/ getJSON. Please help. I am new to javascript.
import { getJSON } from 'wix-fetch';
const baseURL = "https://api.companieshouse.gov.uk"
export function call_companieshouse_api(endpt, search_param){
var api_key = btoa(key)
var url = baseURL + endpt + search_param
getJSON(url, {
method: 'get',
headers: {"Authorization": "Basic " + api_key,
"Content-Type": "application/json",
"Accept": "application/json"},
credentials: "include",
mode: "cors"
})
.then(json => console.log(json.someKey))
.catch(err => console.log(err));
}
I've managed to make it work!
I'm not exactly sure how, but I will explain what I have done (apart from the obvious code change).
I created a new backend file .jsw and in this file is the following code.
import {fetch} from 'wix-fetch';
import btoa from 'btoa'
const baseURL = 'https://api.companieshouse.gov.uk';
var api_key = 'the api key';
export function call_companieshouse_api(endpt, search_param){
var url = baseURL + endpt + search_param;
var base64_key = btoa(api_key)
return fetch(url, {
method: 'GET',
headers: {'Authorization': 'Basic ' + base64_key,
'Content-Type': 'application/json',
'Accept': 'application/json'},
credentials: 'include',
mode: "cors"
}).then(response => response.json());
}
I then have a button click event function with the following code.
export function button1_click(event) {
var search_param = $w('#input1').value;
if (search_param.length <= 1) {
$w('#box1').show();
return;
}
var endpt = "/search/companies?q="
call_companieshouse_api(endpt, search_param)
.then(data => {
console.log(data);
});
}
POSTMAN sample
the same process i want to do it in react-native and i have tried like that
var baseHeaders = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + btoa(client_id + ':' + client_secret)
};
var params = {
client_id: client_id,
client_secret: client_secret,
grant_type: "client_credentials",
}
axios({
method: 'POST',
url: "http://transrv02-ap01.transsyssolutions.com:8080/apex/apxprd/oauth/token",
headers: baseHeaders,
body:params
})
.then((responseJson) => { console.log("clientid---"+responseJson)})
.catch((error) => {
console.error(error);
});
but it have showing 401 error.
Anyone can help me!
thanks in advance....
You can try this...
axios.post('http://transrv02-ap01.transsyssolutions.com:8080/apex/apxprd/oauth/token',
params,
{
headers: baseHeaders
})
.then((responseJson) => { console.log("clientid---"+responseJson)})
.catch((error) => {
console.error(error);
});
Finally I Found My own way not in axios
var baseHeaders = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': "Basic " + btoa(client_id + ":" + client_secret)
};
console.log(JSON.stringify(baseHeaders) + "baseHeaders")
var params = "grant_type=client_credentials";
console.log(JSON.stringify(params) + "params")
return fetch('http://apex/apxprd/oauth/token',{
method: "POST",
body: params,
headers: baseHeaders
}).then((response) => response.json()).then((responsetokenJson) => {
console.log(JSON.stringify(responsetokenJson) + "responseJsonclientid")
var token = responsetokenJson.access_token
console.log("this.props.tokens--" + token)
this.setState({
accessToken: token
})
})
let formData = [];
formData.push('log=' + encodeURIComponent(username) + '&pwd=' + encodeURIComponent(password) + '&wp-submit=Log+In&testcookie=1');
await fetch(window.location.origin + '/wp-login.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: formData[0],
}).then((res) => {
console.log(res);
window.location.reload();
}).catch((error) => {
console.error(error);
});
The fetch returns 200 response whenever I post to wp-login.php so I am not sure what is wrong here. Status Code is also 302 whenever there is a successful login but mine is 200.
I'm building a VueJS application and I'm using JSON web tokens as my auth system. When I log the user, I store the token with localStorage and works fine. I check the headers and it's in the 'Authorization' param.
I pass with axios.defaults.headers.common['Authorization'] = localStorage.getItem('token')
I see the headers and it's okay. But when I execute a get request to an protected route in my API, return 'unauthorized'. But when I pass the header with token manually in the request, works fine.
Somebody know how to pass the header automatically when executing some request?
try this..
//in get request
const auth = {
headers: {Authorization:'JWT ' + localStorage.getItem('token')}
}
axios.get('http://yourapi.com',auth).then(result => {
console.log(result.data)
})
//in post request
const auth = {
headers: {Authorization:'JWT ' + localStorage.getItem('token')}
}
//note:auth will be 3rd parameter in post request
axios.post('http://yourapi.com',{somekey:'some value'},auth).then(result => {
console.log(result.data)
})
You can use axios.create to create a new axios instance with a config object, including the headers. The configuration will be used for each subsequent calls you make using that instance.
Something like this worked for me:
var App = Vue.component('app', {
mounted () {
this.response = null
this.axiosInstance = axios.create({
baseURL: 'http://localhost:5000/',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
}
})
},
data () {
return {
response: this.response,
}
},
methods: {
login () {
this.axiosInstance.post('login', {username: 'test', password: 'test'})
.then(resp => {
this.accessToken = resp.data.access_token
this.axiosInstance.defaults.headers['Authorization'] = 'Bearer ' + this.accessToken
})
.catch(err => this.response = err.response.status + ' ' + err.response.statusText)
},
protected () {
this.axiosInstance.get('protected')
.then(resp => this.response = resp.data)
.catch(err => this.response = err.response.status + ' ' + err.response.statusText)
}
},
template: '<div><button #click="login">Connect</button><button #click="protected">Protected</button></div>'
})
interceptor which includes your auth token in every request as an Authorization header:
axios.interceptors.request.use(
function(config) {
const token = localStorage.getItem('token')
if (token) config.headers.Authorization = `Bearer ${token}`
return config
},
function(error) {
return Promise.reject(error)
}
)
you could place it in the main file, for example main.js
Check whether server get token from header of "Authorization"
axios.defaults.headers.common['Authorization'] = 'Bearer ' + localStorage.getItem('token')
if No. 2 works, then you may want to execute apis even if web is refreshed, then follow:
axios.interceptors.request.use(function (config) {
const token = 'Bearer ' + localStorage.getItem('token');
config.headers.Authorization = `Bearer ${token}`;
return config;
});
For me issue was with capital Headers vs headers.
Should be lower case. My IDE got me the wrong autocomplete (i.e. with capital H)
This works:
await axios.get(url, {
headers: { 'x-custom-header': 'super header value' }
});
This doesn't!
await axios.get(url, {
Headers: { 'x-custom-header': 'super header value' }
});