I am building SPA with react and I run into a problem with code directly from Azure Portal - Quickstart for Javascript. (you can download full code there)
If I create-react-app and I use the code it works just fine and I can authenticate, get token and use it in the post request.
But If I use the SAME code in my app (which is already styled and with all the functionality I need) it gives me Multiple authorities found in the cache. Pass authority in the API overload.|multiple_matching_tokens_detected` error when I authenticate.
Just to clarify authentication goes through and I see I am authenticated, just this error is bugging me and I have no idea how to debug it.
function signIn() {
myMSALObj.loginPopup(applicationConfig.graphScopes).then(function (idToken) {
//Login Success
console.log(idToken); //note that I can get here!
showWelcomeMessage();
acquireTokenPopupAndCallMSGraph();
}, function (error) {
console.log(error);
});
}
function acquireTokenPopupAndCallMSGraph() {
//Call acquireTokenSilent (iframe) to obtain a token for Microsoft Graph
myMSALObj.acquireTokenSilent(applicationConfig.graphScopes).then(function (accessToken) {
callMSGraph(applicationConfig.graphEndpoint, accessToken, graphAPICallback);
}, function (error) {
console.log(error); //this is where error comes from
// Call acquireTokenPopup (popup window) in case of acquireTokenSilent failure due to consent or interaction required ONLY
if (error.indexOf("consent_required") !== -1 || error.indexOf("interaction_required") !== -1 || error.indexOf("login_required") !== -1) {
myMSALObj.acquireTokenPopup(applicationConfig.graphScopes).then(function (accessToken) {
callMSGraph(applicationConfig.graphEndpoint, accessToken, graphAPICallback);
}, function (error) {
console.log(error);
});
}
});
}
The main thing I don`t understand is that the same code works just fine in the fresh create-react-app project, but as I use it in an already existing project (just without authentication) it breaks with mentioned error.
Full code
import React, { Component } from 'react'
import * as Msal from 'msal'
export class test extends Component {
render() {
var applicationConfig = {
clientID: '30998aad-bc60-41d4-a602-7d4c14d95624', //This is your client ID
authority: "https://login.microsoftonline.com/35ca21eb-2f85-4b43-b1e7-6a9f5a6c0ff6", //Default authority is https://login.microsoftonline.com/common
graphScopes: ["30998aad-bc60-41d4-a602-7d4c14d95624/user_impersonation"],
graphEndpoint: "https://visblueiotfunctionapptest.azurewebsites.net/api/GetDeviceList"
};
var myMSALObj = new Msal.UserAgentApplication(applicationConfig.clientID, applicationConfig.authority, acquireTokenRedirectCallBack,
{storeAuthStateInCookie: true, cacheLocation: "localStorage"});
function signIn() {
myMSALObj.loginPopup(applicationConfig.graphScopes).then(function (idToken) {
//Login Success
console.log(idToken);
showWelcomeMessage();
acquireTokenPopupAndCallMSGraph();
}, function (error) {
console.log(error);
});
}
function signOut() {
myMSALObj.logout();
}
function acquireTokenPopupAndCallMSGraph() {
//Call acquireTokenSilent (iframe) to obtain a token for Microsoft Graph
myMSALObj.acquireTokenSilent(applicationConfig.graphScopes).then(function (accessToken) {
callMSGraph(applicationConfig.graphEndpoint, accessToken, graphAPICallback);
}, function (error) {
console.log(error);
// Call acquireTokenPopup (popup window) in case of acquireTokenSilent failure due to consent or interaction required ONLY
if (error.indexOf("consent_required") !== -1 || error.indexOf("interaction_required") !== -1 || error.indexOf("login_required") !== -1) {
myMSALObj.acquireTokenPopup(applicationConfig.graphScopes).then(function (accessToken) {
callMSGraph(applicationConfig.graphEndpoint, accessToken, graphAPICallback);
}, function (error) {
console.log(error);
});
}
});
}
function callMSGraph(theUrl, accessToken, callback) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200)
callback(JSON.parse(this.responseText));
console.log(this.response);
}
xmlHttp.open("POST", theUrl, true); // true for asynchronous
xmlHttp.setRequestHeader('Authorization', 'Bearer ' + accessToken);
var dataJSON = JSON.stringify({ userEmail: null, FromDataUTC: "2012-04-23T18:25:43.511Z" })
xmlHttp.send(dataJSON);
}
function graphAPICallback(data) {
//Display user data on DOM
// var divWelcome = document.getElementById('WelcomeMessage');
// divWelcome.innerHTML += " to Microsoft Graph API!!";
// document.getElementById("json").innerHTML = JSON.stringify(data, null, 2);
}
function showWelcomeMessage() {
console.log("You are looged: " + myMSALObj.getUser().name);
// var divWelcome = document.getElementById('WelcomeMessage');
// divWelcome.innerHTML += 'Welcome ' + myMSALObj.getUser().name;
// var loginbutton = document.getElementById('SignIn');
// loginbutton.innerHTML = 'Sign Out';
// loginbutton.setAttribute('onclick', 'signOut();');
}
// This function can be removed if you do not need to support IE
function acquireTokenRedirectAndCallMSGraph() {
//Call acquireTokenSilent (iframe) to obtain a token for Microsoft Graph
myMSALObj.acquireTokenSilent(applicationConfig.graphScopes).then(function (accessToken) {
callMSGraph(applicationConfig.graphEndpoint, accessToken, graphAPICallback);
}, function (error) {
console.log(error);
//Call acquireTokenRedirect in case of acquireToken Failure
if (error.indexOf("consent_required") !== -1 || error.indexOf("interaction_required") !== -1 || error.indexOf("login_required") !== -1) {
myMSALObj.acquireTokenRedirect(applicationConfig.graphScopes);
}
});
}
function acquireTokenRedirectCallBack(errorDesc, token, error, tokenType)
{
if(tokenType === "access_token")
{
callMSGraph(applicationConfig.graphEndpoint, token, graphAPICallback);
} else {
console.log("token type is:"+tokenType);
}
}
// Browser check variables
var ua = window.navigator.userAgent;
var msie = ua.indexOf('MSIE ');
var msie11 = ua.indexOf('Trident/');
var msedge = ua.indexOf('Edge/');
var isIE = msie > 0 || msie11 > 0;
var isEdge = msedge > 0;
//If you support IE, our recommendation is that you sign-in using Redirect APIs
//If you as a developer are testing using Edge InPrivate mode, please add "isEdge" to the if check
if (!isIE) {
if (myMSALObj.getUser()) {// avoid duplicate code execution on page load in case of iframe and popup window.
showWelcomeMessage();
acquireTokenPopupAndCallMSGraph();
}
}
else {
document.getElementById("SignIn").onclick = function () {
myMSALObj.loginRedirect(applicationConfig.graphScopes);
};
if (myMSALObj.getUser() && !myMSALObj.isCallback(window.location.hash)) {// avoid duplicate code execution on page load in case of iframe and popup window.
showWelcomeMessage();
acquireTokenRedirectAndCallMSGraph();
}
}
return (
<div>
<h2>Please log in from VisBlue app</h2>
<button id="SignIn" onClick={signIn}>Sign In</button>
<button id="SignOut" onClick={signOut}>Sign Out</button>
<h4 id="WelcomeMessage"></h4>
<br/><br/>
<pre id="json"></pre>
</div>
)
}
}
export default test
it gives me Multiple authorities found in the cache. Pass authority in
the API overload.|multiple_matching_tokens_detected` error when I
authenticate
This error is caused because the auth SDK finds multiple matching tokens in cache for the input given to acquireTokenSilent.
Try adding the authority, and user if necessary:
myMSALObj
.acquireTokenSilent(
applicationConfig.graphScopes,
applicationConfig.authority
)
.then(
...
Just to get back to it. I solve it by moving the whole project into fresh create-react-app. It looks like there was more than 1 instance of MSAL object thus more than one call/token at the same time.
Weird but solved my problem.
I know this is an old question, but I'll answer it anyway since I had the same issue.
My workaround for this problem was to just clear the cache whenever this error happened. It worked in my case since this wan't a regularly occurring error for my use case.
In my project's configuration, the site is also set up to refresh and retry when an error like this occurs. So after clearing the cache, the site would reload and would work as expected since there would be no conflicting tokens in the cache.
import { AuthCache } from 'msal/lib-commonjs/cache/AuthCache';
...
const authProvider = new MsalAuthProvider(
configuration,
authenticationParameters,
msalProviderConfig,
);
authProvider.registerErrorHandler((authError: AuthError | null) => {
if (!authError) {
return;
}
console.error('Error initializing authProvider', authError);
// This shouldn't happen frequently. The issue I'm fixing is that when upgrading from 1.3.0
// to 1.4.3, it seems that the new version creates and stores a new set of auth credentials.
// This results in the "multiple_matching_tokens" error.
if (authError.errorCode === 'multiple_matching_tokens') {
const authCache = new AuthCache(
configuration.auth.clientId,
configuration.cache.cacheLocation,
configuration.cache.storeAuthStateInCookie,
);
authCache.clear();
console.log(
'Auth cache was cleared due to incompatible access tokens existing in the cache.',
);
}
I want an API for which if user is not logged in then redirect to homepage /
but this api is access by both web and android.
So i made like this for both web and app .
function requiresLogin(req, res, next) {
if (req.session && req.session.userID) {
return next();
} else {
res.send({status : "logout" , message : "Please Login First"});
}
}
I don't understand how to redirect to homepage / by web-end
because If i am using res.redirect('/homepage') then what about app.
My ajax part is this
$(document).ready(function() {
$.ajax(
{
success: function (result) {
alert(alert.status);
if (result.status === "logout") {
window.location = '/';
}
else {
}
},
error: function (err) {
console.log(err);
}
});
});
but nothing happens.
Thanx in advance.
In my app I can log in to Facebook but I can't logout. When I click button which call logout function I get:
Object { authResponse: null, status: "unknown" }
Here is my code:
function login_to_fb() {
FB.login(function(response) {
if (response.status === 'connected') {
window.location.reload();
}
}, {
scope: 'email'
});
}
function logout_from_fb() {
FB.getLoginStatus(function(response) {
console.log(response);
if (response && response.status === 'connected') {
FB.logout(function(response) {
window.location.reload();
});
}
});
}
I figured out it's because I refresh the page. Without it, scripts works fine but when I log-in and refresh the page then log-out is impossible. How can I save it?
It is possible that the result is cached. Try passing true as the second argument to clear the cache:
FB.getLoginStatus(function(response) {
// this will be called when the roundtrip to Facebook has completed
}, true);
I am working on a project with angular & nodejs, there is a singin and logout function in my controller,
Main.signin(formData, function(res) {
if (res.type == false) {
alert(res.message);
} else {
$localStorage.token = res.token;
$location.path('/'); // redirect to index page.
}
}, function() {
//failed processing.
});
$scope.logout = function() {
Main.logout(function() {
window.location = "/"
window.location.replace("/");
}), function() {
alert("Failed to logout!");
};
};
the logic of the above code is simple but I can't save or delete the token with window.location = "/", but if I comment the window.location = "/", after I execute above methods, then refresh the browser, the token is deleted or saved.
Does anyone have idea about this?
I have created a simple app which used FB Javascript SDK which posts on FB the things which are given in my webpage's textareas.
I am using fb.api for this and the problem is that it works only with my user id(from which I have created the app). For other ids, it doesn't work.Can someone help please? I want other users also to be able to post on their wall once they are logged in.
<html>
<head></head>
<body>
<div id="fb-root"></div>
<label>Give your message here:</label><br/>
<textarea id = "ta"></textarea><br/>
<label>Any image?</label><br/>
<textarea id = "pic"></textarea><br/>
<label>Any link?</label><br/>
<textarea id = "ta_link"></textarea><br/>
<button onclick = "testAPI()">Click To Post!</button>
<script>
// Additional JS functions here
window.fbAsyncInit = function() {
FB.init({
appId : 'AppID', // App ID
channelUrl : 'http://127.0.0.1/channel.html', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
// Additional init code here
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
alert("Connected");
//testAPI();
} else if (response.status === 'not_authorized') {
// not_authorized
login();
} else {
// not_logged_in
login();
}
});
};
function login() {
FB.login(function(response) {
if (response.authResponse) {
//testAPI();
} else {
alert("Can't connect")
}
});
}
function testAPI() {
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
var tbmsg = document.getElementById("ta").value;
var tbimg = document.getElementById("pic").value;
var tblink = document.getElementById("ta_link").value;
var wallPost = {};
wallPost['message'] = tbmsg;
if(tbmsg == "")
{
alert("Message box can't be empty")
}
if(tbimg)
{
wallPost['picture'] = tbimg;
}
if(tblink)
{
wallPost['link'] = tblink;
}
FB.api('/me/feed', 'post', wallPost , function(response) {
if (!response || response.error) {
alert('Error occured');
} else {
alert("Posted");
}
});
}
else
{
alert("Login first")
}
});
}
// Load the SDK Asynchronously
</script>
</body>