I'm able to retrieve an on_behalf_of token from my backend API to use client-side in my page, but if I make two calls to the Microsoft Graph, one immediately after the other, the second one always fails with a 401 unauthorized. The calls are one straight after the other, so definitely within the expiry time window. Is this token one-use only (i.e. it's invalidated straight after use), or am I doing something wrong?
My code is based on this sample, but I've extended it to make another call immediately to the Graph again, as follows:
function useServerSideTokenAgain(token) {
display("4. Call https://graph.microsoft.com/v1.0/me/messages with the server side token");
return fetch("https://graph.microsoft.com/v1.0/me/messages?$select=sender,subject",
{
method: 'GET',
headers: {
"accept": "application/json",
"authorization": "bearer " + token
},
mode: 'cors',
cache: 'default'
})
.then((response) => {
if (response.ok) {
return response.json();
} else {
throw (`Error ${response.status}: ${response.statusText}`);
}
})
.then((profile) => {
display(JSON.stringify(profile, undefined, 4), 'pre');
});
}
then later on, I've changed from the original code:
getClientSideToken()
.then((clientSideToken) => {
return getServerSideToken(clientSideToken);
})
.then((serverSideToken) => {
return useServerSideToken(serverSideToken);
})
.catch((error) => {
...
to this:
getClientSideToken()
.then((clientSideToken) => {
return getServerSideToken(clientSideToken);
})
.then((serverSideToken) => {
return useServerSideToken(serverSideToken);
})
.then((serverSideToken) => {
return useServerSideTokenAgain(serverSideToken);
})
.catch((error) => {
...
My app has delegated "Mail.Read" rights, so the operation itself works fine. Incidentally, if I change the order of operations, the same thing happens in reverse (step 4 works fine, but step 3 throws a 401 unauthorized):
getClientSideToken()
...
.then((serverSideToken) => {
return useServerSideTokenAgain(serverSideToken);
})
.then((serverSideToken) => {
return useServerSideToken(serverSideToken);
})
.catch((error) => {
...
Related
I dont get the token when i use my iphone. I get the token when i use the simulator.
I use nativescript-firebase-plugin and in main.js i do the firebase.init functions.
I have tried with everything i have found on this error, or i dont even know if its a common error. The full init looks like this
firebase.init({
showNotifications: true,
showNotificationsWhenInForeground: true,
onPushTokenReceivedCallback: (token) => {
console.log(`onPushTokenReceivedCallback: ${token}`);
appSettings.setString('firebasemessagekeytoken', token);
},
onMessageReceivedCallback: (message) => {
console.log(`onPushTokenReceivedCallback: ${message.title}`);
}
})
.then(() => {
console.log('[Firebase] Initialized');
})
.catch(error => {
console.log(`error: ${error}`);
});```
I am working on an Angular7 project and have some issues about error handling on http requests.
Here is my Login Component with two functions
export class LoginComponent implements OnInit, OnDestroy {
emailLogin1() {
this.authService.emailLogin1(this.loginForm.value).pipe(delay(1000)).subscribe(
(response) => {
console.log(response);
},
(error) => {
console.log(error);
}
);
}
emailLogin2() {
this.authService.emailLogin2(this.loginForm.value).pipe(delay(1000)).subscribe(
(response) => {
console.log(response);
},
(error) => {
console.log(error);
}
);
}
}
Here is my AuthService with two functions.
export class AuthService {
constructor(private http: HttpClient) {
}
emailLogin1(values): any {
return this.http.post(environment.server + '/auth/emailLogin', values).pipe(
tap(
(response) => {
localStorage.setItem('token', response['token']);
},
(error) => {
console.log(error);
}
)
);
}
emailLogin2(values): any {
return this.http.post(environment.server + '/auth/emailLogin', values).pipe(
tap(
(response) => {
localStorage.setItem('token', response['token']);
}
),
catchError((error) => {
console.log(error);
throw error;
})
);
}
}
When I make a request to the server, if response status is successful, it waits for 1000 ms and then shows the result as expected. But if response returns an error, delay(1000) function not working and error block working immediately. I tried with and without catchError. Both working exactly the same.
The delay operator will only work on events sent through the observable via "next" notifications (in your case, this is a "success"). When an error occurs, it is sent as an "error" notification, and it skips right past your delay operator. If you want to delay the error, you should catch it, introduce a delay, and then re-throw it:
emailLogin1() {
this.authService.emailLogin1(this.loginForm.value).pipe(
delay(1000), // only affects "success"
catchError(error => interval(1000).pipe( // only affects "error"
mergeMap(() => throwError(error)) // re-throw error after our delay
)),
).subscribe(
(response) => {
console.log(response);
},
(error) => {
console.log(error);
}
)
}
I'm trying to take info from a React form and post it to my Rails database, but I get an error "unexpected token '<' at position 0" which means my response is still HTML and not JSON.
Here's my code:
export const createCar = car => {
return dispatch => {
return fetch(`${API_URL}/cars/create`, {
method: "POST",
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify({ car: car })
})
.then(response => response.json())
.then(car => {
dispatch(addCar(car))
dispatch(resetCarForm())
})
.catch(error => console.log(error + 'createCar POST failed'))
}
}
Is there a reason why it's not converting to JSON?
Additionally, I don't seem to be able to drop debugger into my code, or at least in this function - do I need to import it or something?
I'm thinking that your server is sending you back HTML and then you are trying to parse it in response.json()
use a try/catch in this block:
export const createCar = car => {
return dispatch => {
return fetch(`${API_URL}/cars/create`, {
method: "POST",
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify({ car: car })
})
.then(response => {
try {
return response.json()
} catch(error) {
console.error(error);
}
})
.then(car => {
dispatch(addCar(car))
dispatch(resetCarForm())
})
.catch(error => console.log(error + 'createCar POST failed'))
}
I am writing a Fetch request to post new users to an application. The fetch is integrated with a redux store. Response returns [object Object] and response.status returns undefined. I am new to Redux and am wondering if that is where the error is. Here is the code from my actions creator file:
export function createCustomerSuccess(values) {
return {
type: types.CREATE_CUSTOMER_SUCCESS,
values: values
};
}
export function createCustomer(values) {
return function (dispatch, getState) {
console.log('values passing to store', values);
return postIndividual(values).then( (response) => {
console.log('calling customer actions');
console.log(response);
if(response.status === 200){
console.log(response.status);
dispatch(createCustomerSuccess(values));
console.log('create customer success');
}
else {
console.log('not successful');
}
});
};
}
function postIndividual(values) {
console.log('test from post' + JSON.stringify(values));
const URLPOST = "http://myurlisworking/Add";
return fetch (URLPOST, {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Access-Control-Origin": "*"
},
body: JSON.stringify(values)
})
.then(response => response.json())
.then(response => {
console.log('response' + response.status)
});
}
Issue seems like with your fetch expectations. When your first .then gets called after fetch() then you get response.status available there to check.
You can rewrite your fetch like below and see if that resolves.
function postIndividual(values) {
console.log('test from post' + JSON.stringify(values));
const URLPOST = "http://myurlisworking/Add";
return fetch (URLPOST, {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Access-Control-Origin": "*"
},
body: JSON.stringify(values)
})
.then(response => {
console.log('response' + response.status)
return response.ok && response.json();
})
.catch(err => console.log('Error:', err));
}
You can check response.status here ^ and do what you want.
Alternatively you can just do the fetch in postIndividual and handle response in your createCustomer instead.
On the simulator it does not crash and Alerts the error, but in production it is crashes as soon as fetch request suppose to be made and it is impossible to reopen the app until network connection is back (I turn on/off airplane mode for the testing)
here are the snippets of my code
componentWillMount: function(){
NetInfo.isConnected.addEventListener('change',this.handleConnectivityChange)
NetInfo.isConnected.fetch().done((data) => {
this.setState({
isConnected: data
})
console.log('this.state.isConnected: ', this.state.isConnected);
})
},
handleConnectivityChange: function(){
var connected = this.state.isConnected ? false : true
this.setState({isConnected: connected})
console.log('this.state.isConnected11: ', this.state.isConnected);
},
....
goToList: function(replace, listview){
console.log('this.state.isConnected: ', this.props.isConnected);
if (!this.props.isConnected){
AlertIOS.alert('Error', 'Please check your network connectivity')
this.props.removeFetching()
return
}
....
fetch(url)
.then((response) => response.json())
.then((responseData) => {
....
.catch((error) => {
StatusBarIOS.setNetworkActivityIndicatorVisible(false)
AlertIOS.alert('Error', 'Please check your network connectivity')
this.props.removeFetching()
})
.done()
I spent a lot of time trying to find a way to catch exceptions when using fetch() but I was unable to get it working (e.g. using .catch() or a try/catch blog didn't work). What did work was to use XMLHttpRequest with a try/catch blog instead of fetch(). Here's an example I based off of: https://facebook.github.io/react-native/docs/network.html#using-other-networking-libraries
var request = new XMLHttpRequest();
request.onreadystatechange = (e) => {
if (request.readyState !== 4) {
return;
}
if (request.status === 200) {
console.log('success', request.responseText);
var responseJson = JSON.parse(request.responseText);
// *use responseJson here*
} else {
console.warn('error');
}
};
try {
request.open('GET', 'https://www.example.org/api/something');
request.send();
} catch (error) {
console.error(error);
}