I am trying really hard to make MSAL work with Vanilla JavaScript, but it just doesn't work.
Whenever I am trying to click the Sign In button on the Login Page, the Login page just refreshes and nothing happens, the Microsoft Sign In Page is not being shown.
Also no errors are logged to console.
After clicking the Sign In button for like 200 or more times and page refreshing that many times, the Microsoft Sign In page shows up and then it works fine.
Script reference
<script type="text/javascript" src="https://alcdn.msauth.net/lib/1.4.4/js/msal.js" integrity="sha384-fTmwCjhRA6zShZq8Ow5ZkbWwmgp8En46qW6yWpNEkp37MkV50I/V2wjzlEkQ8eWD" crossorigin="anonymous"></script>
JS MSAL code
//Config
const msalConfig = {
auth: {
clientId: "{Client ID}",
authority: "{Authority}",
redirectUri: "{Base App URL}/Dashboard", //This URL is registered in Microsoft AAD
navigateToLoginRequestUrl: false
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: true,
}
};
//Login Request Object
const loginRequest = {
scopes: ["User.Read"],
prompt: 'login',
};
//Initialize MSAL
var myMSALObj = new Msal.UserAgentApplication(msalConfig);
myMSALObj.handleRedirectCallback(authRedirectCallBack);
//Handle Callback
function authRedirectCallBack(error, response) {
if (error) {
console.log(error);
} else {
if (response.tokenType === "id_token") {
console.log("id_token acquired at: " + new Date().toString());
if (myMSALObj.getAccount()) {
showWelcomeMessage(myMSALObj.getAccount());
}
} else if (response.tokenType === "access_token") {
console.log("access_token acquired at: " + new Date().toString());
accessToken = response.accessToken;
try {
callMSGraph(graphConfig.graphMailEndpoint, accessToken, updateUI);
} catch (err) {
console.log(err)
}
} else {
console.log("token type is:" + response.tokenType);
}
}
}
$(document).on("click", "#btn-testing-msal", function () {
myMSALObj.loginRedirect(loginRequest);
});
Any help will be appreciated, Thanks in advance
Debug your frontend code like this, just trying to make sure where caused your problem, and it may have some help:
Related
I'm trying to implement silent login in oidc-client to use with Angular 2
How can use oidc client to silently check if user is already logged in (idsvr4) and display the login details.
the following code works, but i need to refresh the page
idsvr 4 client
// JavaScript Client
new Client
{
ClientId = "js",
ClientName = "JavaScript Client",
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
RedirectUris = { "http://localhost:5002/callback.html" },
PostLogoutRedirectUris = { "http://localhost:5002/index.html" },
AllowedCorsOrigins = { "http://localhost:5002" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api1",
},
RequireConsent=false,
AllowOfflineAccess = true
}
client side code
var config = {
authority: "http://localhost:5000",
client_id: "js",
redirect_uri: "http://localhost:5002/callback.html",
silent_redirect_uri: "http://localhost:5002/callback.html",
response_type: "id_token token",
scope: "openid profile api1 offline_access",
post_logout_redirect_uri: "http://localhost:5002/index.html",
// Number of seconds before the token expires to trigger
// the `tokenExpiring` event
accessTokenExpiringNotificationTime: 4,
// Do we want to renew the access token automatically when it's
// about to expire?
automaticSilentRenew: false,
// Do we want to filter OIDC protocal-specific claims from the response?
filterProtocolClaims: false,
// use localStorage
userStore: new Oidc.WebStorageStateStore({ store: window.localStorage })
};
var mgr = new Oidc.UserManager(config);
// You can hook a logger to the library.
// Conveniently, the methods exposed by the logger match
// the `console` object
Oidc.Log.logger = console;
// When a user logs in successfully or a token is renewed, the `userLoaded`
// event is fired. the `addUserLoaded` method allows to register a callback to
// that event
mgr.events.addUserLoaded(function (loadedUser) {
console.log("$$$$$$$$$$$$$$$$$$$$$$$ added");
});
// Same mechanism for when the automatic renewal of a token fails
mgr.events.addSilentRenewError(function (error) {
console.error('$$$$$$$$$$$$$$$$$$$$$$$ error while renewing the access token', error);
});
// When the automatic session management feature detects a change in
// the user session state, the `userSignedOut` event is fired.
mgr.events.addUserSignedOut(function () {
alert('The user has signed out');
});
mgr.getUser().then(function (user) {
if (user) {
log("User logged in", user.profile);
}
else {
log("User not logged in");
// log("*****************************************************");
mgr.signinSilent()
.then(function (newUser) {
console.log("doneeeeeeeeeeeeeeeeeeeee");
console.log(newUser);
console.log(newUser.profile);
}).catch(function (e) {
console.log("======== " + e);
});;
mgr.signinSilentCallback().then(function (newUser) {
console.log("doneeeeeeeeeeeeeeeeeeeee");
console.log(newUser);
console.log(newUser.profile);
}).catch(function (e) {
console.log("&&&&&&&&&&&& "+e);
});
}
});
no user is getting returned in either methods of silentSignIn
I want to get if user is logged in and retrieve the information as soon as the client is open.
Or if there's a better way to do this in angular 2 then it's better.
I had the same problem. I managed to solve it by using the following signin() method and by managing the process sign in response:
function signin() {
manager.createSigninRequest().then(function (req) {
window.location = req.url;
}).catch(function (err) {
log(err);
});
}
manager.processSigninResponse().then(function (response) {
log("signin response success", response);
}).catch(function (err) {
});
manager.events.addUserLoaded(function (user) {
manager.getUser().then(function () {
log("User logged in", user.profile);
});
});
function api() {
mgr.getUser().then(function (user) {
var url = "http://localhost:5001/identity";
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = function () {
log(xhr.status, JSON.parse(xhr.responseText));
}
xhr.setRequestHeader("Authorization", "Bearer " + idToken);
xhr.send();
});
}
I'm using Parse Server + Parse JS Sdk to handle user login through Facebook. Everything works fine until I refresh web browser. What data should I store after login process is done? I belive that FB AccessToken is important to keep Facebook Session, but what about Parse Session.
Current code:
login: function (callback) {
console.log('loggin in...')
Parse.FacebookUtils.logIn('user_likes,email', {
success: function (parseUser) {
if (!parseUser.existed()) {
console.log('signed up and logged in!')
} else {
console.log('logged in!')
}
console.log('parse user is: ', parseUser.id)
if (callback) { callback() }
},
error: function (parseUser, error) {
console.log('login cancelled: ', error.message)
}
})
}
You don't need to manually store anything. You can use the parse function:
Parse.User.current()
To see if there is already a user logged-in.
We made this function:
function userAuthenticated(){
if(Parse.User.current() === null){
return false;
}
if(Parse.User.current().authenticated()){
return true;
}
else{
return false
}
}
I am trying to use Firebase's Facebook authentication on a webpage, but I get this error:
Login failed Error: Invalid authentication credentials provided.
at Error (native)
at http://45.55.203.213/js/firebase.js:160:367
at e (http://45.55.203.213/js/firebase.js:140:400)
Here's my Javascript code:
var ref = new Firebase("https://fantasy-smash-bros.firebaseio.com/");
function FBLogin() {
ref.authWithOAuthPopup("facebook", function(error, authData) {
if (error) {
console.log("Login failed", error);
} else {
loginWithAuthData(authData);
}
});
}
function loginWithAuthData(authData) {
username = authData.facebook.displayName;
avatarURL = authData.facebook.cachedUserProfile.picture.data.url;
userID = authData.facebook.id;
}
function attemptLogin() {
var user = ref.getAuth();
if (user) {
loginWithAuthData(user);
} else {
$("#fb-login").click(function () {
FBLogin();
});
}
}
$(document).ready(function () {
attemptLogin();
});
Note: I have imported firebase.js. Here's a copy of the Javascript I used.
I believe I have setup everything correctly: adding Firebase's callback URL to my Facebook app's whitelist, enabling Facebook authentication on the Firebase app. But I am still stumped on what to do. Any help would be greatly appreciated.
I am making an angularJS application, and I plan to use Firebase for simple authentication.
My index.html file includes
<script src="https://cdn.firebase.com/js/simple-login/1.6.2/firebase-simple-login.js"></script>
<script src="scripts/login.js"></script>
My login.js looks like this at the moment:
$(document).ready(function(){
var myRef = new Firebase("https://my_app.firebaseio.com");
var auth = new FirebaseSimpleLogin(myRef, function(error, user) {
if (error) {
// an error occurred while attempting login
console.log(error);
} else if (user) {
// user authenticated with Firebase
console.log("User ID: " + user.uid + ", Provider: " + user.provider);
} else {
// user is logged out
}
});
var authRef = new Firebase("https://my_app.firebaseio.com/.info/authenticated");
authRef.on("value", function(snap) {
if (snap.val() === true) {
alert("authenticated");
} else {
alert("not authenticated");
}
});
auth.login('password', {
email: 'user#host.com',
password: 'password',
});
console.log(auth);
});
All I really want to do with this is test whether I can log in, and what the auth object will look like after a login.
Later, I will integrate the login into a ng-model to pass the data that way rather than just passing it hard coded.
The problem right now is that this code doesn't even run, I get an error back from the javascript console:
Uncaught ReferenceError: Firebase is not defined
Why is this happening?
It seems you haven't included the firebase.js script.
Only the firebase-simple-login.js isn't enough, it require firebase.js.
<script src="https://cdn.firebase.com/js/client/1.0.17/firebase.js"></script>
<script src="https://cdn.firebase.com/js/simple-login/1.6.2/firebase-simple-login.js"></script>
<script src="scripts/login.js"></script>
Have searched everywhere for this without luck. I'm getting this error when running PhoneGap app on device (works fine in browser):
Given URL is not allowed by the Application configuration.: One or more of the given URLs is not allowed by the App's settings. It must match the Website URL or Canvas URL, or the domain must be a subdomain of one of the App's domains.
This is because I haven't added the host to the facebook app configuration. BUT, PhoneGap/Cordova accesses the app through the file:/// protocol, so there's no domain for me to add to Facebook.
Potential options: 1) Figure out how to use a cordova native plugin (this is hard because we're using Parse), 2) Switch Cordova to use localhost instead of file:// (not sure how to do this).
I've been down this road and ultimately went with option #1. Since we're not really dealing with a website there is no domain to add. Cordova needs to use file:// I don't think there is any way around it. The trick with using the plugin is keeping the login status in sync with Parse (use Parse.FacebookUtils.logIn). He's some code that should help you out. This is how I check the login status:
try {
console.log("Trying to get FB login status");
return FB.getLoginStatus(function(response) {
var accessToken, currentView, expDate, facebookAuthData, uid, user;
console.log(response);
if (response.status === "connected") {
uid = response.authResponse.userID;
accessToken = response.authResponse.accessToken;
console.log("Logged in!");
user = Parse.User.current();
if (user != null) {
console.log("we have a user");
} else {
console.log("we don't have a user... need to login with parse");
expDate = new Date(response.authResponse.expirationTime);
facebookAuthData = {
id: response.authResponse.userID + "",
access_token: response.authResponse.accessToken,
expiration_date: expDate.toISOString()
};
Parse.FacebookUtils.logIn(facebookAuthData, {
success: function(_user) {
return console.log("Logged in with Parse!");
},
error: function(error1, error2) {
return console.log("Unable to create/login as Facebook user");
}
});
}
} else {
// not logged in to fb...
}
});
} catch (e) {
return console.log(e);
}
Here's how I handle logins:
return FB.Event.subscribe("auth.authResponseChange", function(response) {
var expDate, facebookAuthData;
if (response.status === "connected") {
console.log(response.status);
try {
expDate = new Date(response.authResponse.expirationTime);
facebookAuthData = {
id: response.authResponse.userID + "",
access_token: response.authResponse.accessToken,
expiration_date: expDate.toISOString()
};
return Parse.FacebookUtils.logIn(facebookAuthData, {
success: function(_user) {
//return window.location.hash = "loginsuccess";
},
error: function(error1, error2) {
console.log("Unable to create/login to as Facebook user");
}
});
} catch (ex) {
return console.log("parse login error " + ex);
}
} else if (response.status === "not_authorized") {
// handle not auth event
} else {
// take them home?
}
});
}