Aurelia Push State App Reload on Login and Logout - pushstate

When configuring Push State with Aurelia and Visual Studio, I am getting an odd behavior where after I select login my entire app reloads instead of the router just pushing to the homepage. This also happens when I logout, I get to the login screen and it refreshes the entire app. I am using Aurelia Auth. Any assistance would be much appreciated.

I think I had the exact same issue some time ago and this was one of the reasons I switched back to pushState = false (but my infos may be helpful for you).
Anyways, the following issue describes what I was facing: https://github.com/paulvanbladel/aurelia-auth/issues/55
The problem is, internally the plugin sets href:
Login - https://github.com/paulvanbladel/aurelia-auth/blob/master/src/authentication.js#L95-L99
if (this.config.loginRedirect && !redirect) {
window.location.href = this.getLoginRedirect();
} else if (redirect && isString(redirect)) {
window.location.href = window.encodeURI(redirect);
}
Logout - https://github.com/paulvanbladel/aurelia-auth/blob/master/src/authentication.js#L139-L143
if (this.config.logoutRedirect && !redirect) {
window.location.href = this.config.logoutRedirect;
} else if (isString(redirect)) {
window.location.href = redirect;
}
What you need to do is avoid both conditions, i.e. set loginRedirect and logoutRedirect to the empty string (''). Then, do the navigation on your own via Aurelias router as I did in my example from the GH issue:
return this.auth.login(userInfo)
.then(response => {
console.log('You signed in successfully.');
this.router.navigate('/contents');
})
Of course, do the same router navigation on your logout method.

Related

Keycloak return url

Keycloak version 16.1.1
keycloak.init({onLoad: 'login-required'}).then(async function (authenticated: any) {
if (!authenticated) {
display error...
} else {
use token to call rest and go to account page
}
This all works fine. After login, account page is displayed with url
http://localhost:4200/accnt
After couple of second, page flickers and url changes to
http://localhost:4200/accnt#state=5758b505-a101-48a3-a3a2-d899bf3e0da2&session_state=a5d6e548-9ebc-4666-bc41-e92f00e4f216&code=8c93d0cf-5dde-40f3-bf1f-e81d2449f1d5.a5d6e548-9ebc-4666-bc41-e91a00e4f216.c7b376cb-05a2-49fa-8164-b8c932598bbd
Why is it happening and how can I stop this flicker and url change ?
Try changing the initOptions from { onLoad: 'login-required' } to
{
onLoad: 'check-sso',
silentCheckSsoRedirectUri: window.location.origin + '/silent-check-sso.html',
}
And adding a silent-check-sso.html file next to your index.html with a content:
<html><body><script>parent.postMessage(location.href, location.origin)</script></body></html>
Hope it helps!

Ionic - flashes with wrong starting page on app start

Ive created 2 route guards... one which checks if the user is logged in and one if they are unauthenticated
When the app starts, very briefly it determines, while looking for the localstorage cookie, that the user doest exist and so shows the unauth page (i.e login page)
Im wondering what is the best approach to solve this - in my eyes the authguard with observale to see if the user is logged in or not was the best approach but there is that split second while the code runs that it cannot determine and it wants to show something.
Anyone have any similar issues/creative solutions to solve it.
I had this same issue a few months ago, and I solved it by creating an Auth Guard and returning a promise...
auth.guard.ts
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
): Observable<boolean> | Promise<boolean> | boolean {
return new Promise(resolve => {
const userAuthObs = this.afAuth.user.subscribe(user => {
if (user) {
resolve(true);
} else {
this.router.navigate(['signup']);
resolve(false);
}
});
});
}
The app just continues to load normally while it waits for this promise to decide where to direct the user.
You can watch a great video about creating auth guards here...
https://www.youtube.com/watch?v=RxLI9_ub6PM

gapi.analytics.auth.isAuthorized is always false on page load

I'm using gapi.analytics for Embed API and I'm verifying the authentication using the below code in gapi.analytics.ready function.
if (gapi.analytics.auth.isAuthorized()) {
onAuthorize();
} else {
gapi.analytics.auth.on('success', onAuthorize);
}
but gapi.analytics.auth.isAuthorized() is always returning false on page load.
How I can fix this?
You can do it this way:
gapi.analytics.auth.on('needsAuthorization', function() {
console.log('User is not Authorized!');
});
When invoking the gapi.analytics.auth.authorize method, an initial check is made to see if the user is currently signed in. If the user is not signed in, this event is fired to indicate that further authorization is required.

How to ensure that a controllers action is only being called once in sails.js app ..?

I am trying to implement user authentication in my sails app.. But I am encountering a problem in different controllers that their action are being called twice.. I have checked from my browser and the request is only being sent once.. Here is an example..
// api/controllers/AuthController.js
...
logout: function (req, res) {
console.log("Loggin out");
req.logOut();
res.json({message: 'Logged out succesfully'});
},
...
Following is my config/routes.js file. (using get for many action just for sake of ease for testing api..)
module.exports.routes = {
// By default, your root route (aka home page) points to a view
// located at `views/home/index.ejs`
//
// (This would also work if you had a file at: `/views/home.ejs`)
'/': {
view: 'home/index'
},
// testing the api
'get /users/check' : 'UserController.test',
'get /login' : 'AuthController.process',
'get /logout' : 'AuthController.logout',
'get /signup': 'UserController.add',
'get /verify/username/:username?' : 'UserController.checkUsername',
'get /verify/email/:email?' : 'UserController.checkEmail',
// add friend
'get /:user?/addfriend': 'FriendController.addFriend',
// accept request
'get /:user?/friendrequest/:request?/accept': 'FriendController.acceptRequest',
};
I have applied the isAuthenticated policy on this action.. which is like
module.exports = function(req, res, next) {
if(req.isAuthenticated()) {
console.log("Valid User");
return next();
}
else {
console.log("User not logged in");
return res.json({error: "Please login"});
}
};
No whenever I call <myhost>/logout I get the following json back..
{
"error": "Please login"
}
and here is the output on the server..
Valid User
Loggin out
User not logged in
This means that my controller's action is being called twice.. and this is not the problem with only this controller. The UserController.add action has the same problem. I seem to be doing every thing fine but I don't know where this problem is coming from. Can any one suggest how can I debug it . Or what could be the root of the problem. As far as I have check..
Browser is not sending the request twice.
The Controller's action is being called twice and so are the middleware assosiated with it.
Oh i have the same Problem a few weeks ago.
Sails also call the middleware on static files (like your styles.css). Console.log the req-object than you see what your browser requested.
There a two Ways to handle this Problem:
1.) Try to set skipAssets: true in your route (see: http://beta.sailsjs.org/#/documentation/concepts/Routes/RouteTargetSyntax.html)
2.) In your policy add an if-condition to skip assets (like ".js", ".css" and so on).

Facebook login hangs at "XD Proxy" when page is installed via Chrome Web Store

The created the following web application:
http://www.web-allbum.com/
I also added it to the Chrome Web Store:
https://chrome.google.com/webstore/detail/idalgghcnjhmnbgbeebpdolhgdpbcplf
The problem is that when go to the Chrome Web Store and install this app the Facebook login windows hangs at a "XD Proxy" window. While the connect itself works, this blank window can confuse the users.
I did my research, and this seems to be a Chrome issue:
https://code.google.com/p/chromium/issues/detail?id=59285#c26
If you uninstall the app from Chrome, the problem disappears.
Is there any workaround for this problem?
Similar stackoverflow questions:
Facebook connect login window locking in Chrome
FB.login dialog does not close on Google Chrome
facebook connect blank pop up on chrome
https://stackoverflow.com/questions/4423718/blank-page-with-fb-connect-js-sdk-on-after-permission-request
This is my Facebook connect in case it helps:
FB.init({
appId : window.__FACEBOOK_APP_ID__,
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true, // parse XFBML
channelUrl : window.__MEDIA_URL__ + 'channel.html', // channel.html file
oauth : true // enable OAuth 2.0
});
FB.XD.Flash.init();
FB.XD._transport = "flash";
if (A.networks.facebook.connected) {
FB.getLoginStatus(function (response) {
// Stores the current user ID for later use
that.network_id = response.authResponse.userID;
if (!response.authResponse) {
// no user session available, someone you dont know
A.networks.facebook.connected = false;
}
callback();
});
}
else {
callback();
}
};
The Solution
Thanks to the reekogi reply I was able to workaround this issue. Here is the full implementation:
In order to avoid the XD Proxy problem, you have to connecte to Facebook without using the FB.login, this can be achieved by manually redirecting the user to Facebook page.
I had this login function in my code:
_facebook.connect_to_network = function (callback) {
FB.login(function (response) {
if (response.authResponse) {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function (response) {
// Stores the current user Id for later use
that.network_id = response.id;
console.log('Good to see you, ' + response.name + '.');
callback();
});
}
else {
console.log('User cancelled login or did not fully authorize.');
that.connected = false;
callback();
}
}, {scope: window.__FACEBOOK_PERMS__});
};
Which I replaced by this code:
_facebook.connect_to_network = function (callback) {
var url = 'https://www.facebook.com/connect/uiserver.php?app_id=' + window.__FACEBOOK_APP_ID__ + '&method=permissions.request&display=page&next=' + encodeURIComponent(window.__BASE_URL__ + 'authorize-window?my_app=facebook&my_method=login') + '&response_type=token&fbconnect=1&perms=' + window.__FACEBOOK_PERMS__;
window.open(url);
};
The new code opens a popup which connects to Facebook and returns to the url specified in the 'next' parameter. I added some extra parameters in this callback url so that the javascript code could check for it and close the popup.
This code is executed when the Facebook redirects to the callback url:
_facebook.parse_url_params = function () {
// This is the popup window
if (URL_PARAMS.my_method === 'login') {
window.opener.A.networks.facebook.connected = true;
self.close();
}
};
URL_PARAMS is just a helper object that contains all the url parameters.
I still believe that this is a Chrome issue, but since this workaround has worked and solved my problem I am marking this question as solved.
Could you call a javascript redirect to get permissions then redirect back to the http://www.web-allbum.com/connected uri?
I described this method in detail here ->
Permissions on fan page
EDIT:
The method I demonstrated before will be deprecated when OAuth 2.0 comes into the requirements.
Here is the code, adapted for OAauth 2.0 (response.session is replaced with response.authResponse)
<div id="fb-root"></div>
<script>
theAppId = "YOURAPPID";
redirectUri = "YOURREDIRECTURI"; //This is the page that you redirect to after the user accepts the permissions dialogue
//Connect to JS SDK
FB.init({
appId : theAppId,
cookie: true,
xfbml: true,
status: true,
channelURL : 'http://yourdomain.co.uk/channel.html', // channel.html file
oauth : true // enable OAuth 2.0
});
//Append to JS SDK to div.fb-root
(function() {
var e = document.createElement('script');
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
e.async = true;
document.getElementById('fb-root').appendChild(e);
}());
//Check login status and permissions
FB.getLoginStatus(function(response) {
if (response.authResponse) {
// logged in and connected user, someone you know
} else {
//Redirect to permissions dialogue
top.location="https://www.facebook.com/connect/uiserver.php?app_id=" + theAppId + "&method=permissions.request&display=page&next=" + redirectUri + "&response_type=token&fbconnect=1&perms=email,read_stream,publish_stream,offline_access";
}
});
</script>
Just tried and tested, worked fine in chrome.
I didn't try the solution proposed by Cesar, because I prefer to stick with Facebook's official javascript SDK.
Nevertheless I would like to add a few observations:
Indeed, the blocking problem only happened on Chrome after installing from Chrome Web Store. Uninstalling the web app solves the problem. (tested with legacy authentication method, without oauth 2.0). After closing the XD Proxy popup manually, my application was working properly.
After switching to asynchronous FB.init() and enabling oauth 2.0 option, my application would not even get a valid facebook connect status at login time ({authResponse: null, status: "unknown"})... Again, uninstalling it from the Chrome Web Store, it's working... ({authResponse: Object, status: "connected"})
No problem encountered with Safari, in any of these cases.
In IE8 - this can be caused by your flash version. I tried everything and nothing worked until I disabled flash. More details from this blog:http://hustoknow.blogspot.com/2011/06/how-facebooks-xdproxyphp-seemed-to-have.html#comment-form
Open a new browser tab in Chrome and see if you have the Facebook 'App' installed. If so, drag it to the bottom right corner to uninstall. Once uninstalled the XD Proxy will work.
Reference: facebook connect blank pop up on chrome
I was experiencing same problem for all browsers. When user clicked "login" button, a popup opened and hanged; and unless user killed browser process, it caused a high load on CPU. If user managed to see "allow" button and click it however, then it appeared a "xd proxy" blank window and nothing happened. That was the problem.
After long investigations, I noticed my new JS code which proxies setInterval/clearInterval/setTimeout/clearTimeout methods, caused this problem. Code is as follows:
window.timeoutList = new Array();
window.intervalList = new Array();
window.oldSetTimeout = window.setTimeout;
window.oldSetInterval = window.setInterval;
window.oldClearTimeout = window.clearTimeout;
window.oldClearInterval = window.clearInterval;
window.setTimeout = function(code, delay) {
window.timeoutList.push(window.oldSetTimeout(code, delay));
};
window.clearTimeout = function(id) {
var ind = window.timeoutList.indexOf(id);
if(ind >= 0) {
window.timeoutList.splice(ind, 1);
}
window.oldClearTimeout(id);
};
window.setInterval = function(code, delay) {
window.intervalList.push(window.oldSetInterval(code, delay));
};
window.clearInterval = function(id) {
var ind = window.intervalList.indexOf(id);
if(ind >= 0) {
window.intervalList.splice(ind, 1);
}
window.oldClearInterval(id);
};
window.clearAllTimeouts = function() {
for(var i in window.timeoutList) {
window.oldClearTimeout(window.timeoutList[i]);
}
window.timeoutList = new Array();
};
window.clearAllIntervals = function() {
for(var i in window.intervalList) {
window.oldClearInterval(window.intervalList[i]);
}
window.intervalList = new Array();
};
Removing these lines solved my problem. Maybe it helps to who experiences the same.
It appears this has been fixed in Chrome. No longer happens for us in Mac Chrome 15.0.874.106
Another workaround is to use this code after you call FB.init():
if (/chrome/.test(navigator.userAgent.toLowerCase())) {
FB.XD._origin = window.location.protocol + '//' + document.domain + '/' + FB.guid();
FB.XD.Flash.init();
FB.XD._transport = 'flash';
}
The pop-up window remains open and blank, but I found that in my Chrome Web Store app, the authentication goes through when this code is used.
This bug is also filed on Facebook Developers here: http://developers.facebook.com/bugs/278247488872084
I've been experiencing the same issue in IE9, and it seemed to stem from upgrading to Flash Player 10. The answers suggested already did not work for me and I'd lost hope in trying to fix it since finding an open bug at Facebook covering it. But Henson has posted an answer on a similar question that fixed it for me. In the JavaScript in my site master I removed the lines
FB.UIServer.setLoadedNode = function (a, b) {
//HACK: http://bugs.developers.facebook.net/show_bug.cgi?id=20168
FB.UIServer._loadedNodes[a.id] = b;
};
and now it works. (N.B. I have not checked to see if the IE8 issue those lines were intended to overcome returns.)