I'm doing auth with facebook that opens new tab and redirects user to backend on port 8080 after he is authenticated. Then he gets redirected back to app. From there I want to close the window and call function on opener window window.opener.functionAfterFinish() that will let it know auth finished. Problem is that I have to have that function in index.html for it to work. If I create functionAfterFinish(): void{...} in component, it won't get called.
What are my options ? How should I put that function in component and get it executed ?
Well, I'll suggest you to use cookies.
Firstly, You need to create cookies while redirecting to the new tab.
For Example : this._cookieService.createCookie('fbCookies', 'success', 3);
Now, you need to check the cookies by using a set interval in the method where you'are getting the authentication response.
Example-
let interval = setInterval(function(){
let cookie = this._cookieService.readCookie('fbCookies');
if (cookie === 'success') {
newWindow.close();
clearInterval(interval);
}else if (cookie === null) {
clearInterval(interval);
newWindow.close();
}
}, 5000);
Thus, as soon as you'll get the success tab will be close.
You have to set your component service or method on the window object
Inside your service/component :
askFacebook(){
(window as any).functionAfterFinish=this.functionAfterFinish.bind(this);
// Do ask facebook
}
Be sure to run the callback in the angular zone.
(Sorry for brevity, i am answering on my phone. If you have questions, don't hesitate to post a comment)
Related
I have a scenario where I need to execute a logout function in php, this function deletes the user from DB and informs another application through sockets. This function should be called when the user closes the browser or tab. I have tried various scenarios posted by others and nothing seems to work in chrome(Version 57.0.2987.110) and firefox.
Following is the examples I tried along with links,
My sample Code
<script type="text/javascript">
var str = 'delete';// this will be set to 'Apply' if the form is submitted.
function logout(){
location.href = 'Logout.php';
}
function pageHidden(evt){
if (str==='delete')
logout();
}
window.addEventListener("pagehide", pageHidden, false);
</script >
Examples I tried....
// 1st approach
//window.addEventListener("beforeunload", function (e) {
/// var confirmationMessage = "Do you want to leave?";
// (e || window.event).returnValue = confirmationMessage;
// return confirmationMessage;
// });
// 2nd approach
// window.onbeforeunload = myUnloadEvent;
// function myUnloadEvent() {
// console.log("Do your actions in here")
// }
// 3rd approach
$(window).on('beforeunload', function() {
return 'Your own message goes here...';
});
checked the following urls
1. window.onunload is not working properly in Chrome browser. Can any one help me?
2. https://webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/ - I followed this approach. Tried some other approaches as well.
3. I can't trigger the unload event in Chrome etc....
Any help is much appreciated, because if the user closes the browser an entry remains in the DB and this is not allowing any new user to login.
You shouldn't rely on JavaScript for sever-side code. It's actually entirely possible to achieve what you're looking for, purely with PHP. Just make sure to 'kill' the session before starting it:
session_set_cookie_params(0);
session_start();
session_set_cookie_params(0) will tell the browser that any exisiting session should only exist for another 0 seconds. Essentially, this means that a user will automatically 'log out' immediately. This way, you don't have to rely on client-side code, which is susceptible to all measure of interrupts such as power outages.
Hope this helps! :)
The correct way to logout is related to how they are logged in.
In PHP, the login state is typically managed by sessions. By default the timeout is 24 minutes of inactivity, but you can easily reduce it.
When a user logs out, you typically reset one or more session variables, and, while you’re at it, kill off the current session, and delete the session cookie.
However, you cannot rely on a user to log out, and many typically just wander off. This is why there is always a relatively short timeout on sessions.
If you want to automatically logout when the tab is closed, you will need JavaScript to intercept the process with window.onbeforeunload and then use Ajax to send the logout to the server.
As regards the database, you normally do not record the login state in the database. You may record the login time, and if you like, the logout time, but remember that may be never.
I have the following in my js file that is included in the main .cshtml page of my ASP.NET MVC application:
var ajax_call = function () {
$.ajax({
type: "GET",
cache: false,
url: "/Session/Index/",
success: function (result) {
if (!(result.length > 0)) {
window.location.href = '/Home/Index/'
}
}
});
};
var interval = 1000 * 60 * .2; // where X is your every X minutes---.2 -> every 12 seconds
setInterval(ajax_call, interval);
The goal is to check if the session is still valid (the SessionController only returns a result if the session is active), otherwise the browser gets redirected to Home/Index, where HomeController has a global authorization attribute that redirects to the login page if the log in is not a valid session.
My questions are, is this a valid approach? It works (if I login in with a user, then open a new window and log in with the same user in the new window, the old window gets redirected to the login screen shortly after, depending on where it is in the 12 second cycle), but is there a way I can do such a thing entirely in the backend?
Thank you.
The goal is to check if the session is still valid
This is not a good approach, because a request to a server will rest the session timeout to 0. It means you are making session alive forever. If a user forgets to close the browser and leave the computer open, other can still access the account.
Here is the approach I use in my websites inspired by banking/credit card websites.
By default, Session Time out is 20 minutes (you can adjust the way you want). So, I let timer run at client side. When it reaches 19 minutes, I display a popup message with a minute count down timer.
If use does not close the popup, I redirect to logout page.
Here is the concept and sample code, but you do not need to use Telerik control to achieve it.
Scenario: I have an AngularJS app that uses Google's auth.
Depends on the resource, when Angular calls (my) backend, it can return a response asking for Oauth token.
In this case, Angular will show a popup (not a Bootstrap's modal dialog) with that redirect URL.
Google will authenticated, ask for permission, and send the user back to me.
There is a callback URL that will process the 'code' and get the real token. This callbak URL will be called inside that popup.
When I get the token, the popup should close itself, and notify Angular to try that last request again (now I have the token in user's session)
Problem: how can a popup emit an Angular event?
Actually, it doesn't need to be that $rootScope.$emit, but just a way to notify Angular.
I saw this option, but it doesn't seem good for Angular :(
you can use localStorage events, take a look at this demo: http://html5demos.com/storage-events
// this should be in the main page
$window.addEventListener('storage', function(event) {
if(event.key === 'login-notification') {
// got it!
// you can get the value from
// the notification with "event.newValue"
}
}, false);
// send the event with just a setItem from the popup
$window.localStorage.setItem('login-notification', 'ayy');
Create a service first.
app.service("servicee", function(){
return {
set : function(k,v){
this[k] = v;
},
get : function (k){
return this[k]
}
}
});
Now in the popup you can set the token in the service, now you have the value available throught out the app. Also you can $watch the specific key in the service and take some action when the value is set.
I am using Meteor with React and is facing a problem on log out function. When I open more than 2 tabs on the same browser, If I logged out from one tab then the other opening tabs would not be logged out but will be hang if I using it. There are only 2 ways to log out: close the tab or refresh it.
I try the same for log in function and it worked, log in status is synced between all opening tabs.
My current code to call the log out function:
signOut: function(event) {
event.preventDefault();
Meteor.logout();
this.props.history.pushState(null, "/");
},
Thank for the helps.
Update:
I checked the websocket, it's seem that the server did send the logout status but my client code did not call the logout method (or it is hang). Then every data in the hang tab is still existing. But I don't know how to check further more.
I found the cause. It was because I try to avoid sending data on Meteor.publish() if users is not logged in. The problem is I do not return anything on that case.
My solution is return this.ready() when the user is not logged in like this:
Meteor.publish("myCollections", function (){
if (!this.userId) return this.ready();
return MyCollections.find({owner: this.userId});
});
From the meteor documentation, you can use Meteor.logoutOtherClients() before calling Meteor.logout().
Normal (as in non-incognito) browser tabs share the same session resume token. The Meteor server will update them all when the user status changes for the associated session.
It is possible to reactively track the login status using 2 reactive calls:
Meteor.userId() - return the user's id or null if no user is logged in.
Meteor.loggingIn() - returns true if the user is currently in the transient state of logging in and false otherwise.
The status may take a few seconds to update across tabs, but it will happen eventually. It is up to you to detect those changes and act upon them.
You can easily test this by running the following reactive code in the consoles of 2 open tabs connected to the same Meteor server:
Tracker.autorun(function() {
if (Meteor.loggingIn()) {
console.info('logging in');
} else if (Meteor.userId()) {
console.info('logged in');
} else {
console.info('logged out');
}
});
Try to log in and log out from one of the tab and watch the other follow along.
Using this technique, you could track the login state and change your application state and do something accordingly (e.g, redirect/render a different view or layout) when the login state changes.
Trying to get Facebook to authenticate my users via a javascript popup. Right now, I have:
<input type="button" value="Connect with Facebook" onclick="window.open('https://graph.facebook.com/oauth/authorize?client_id=XXXXXXXXXXX&redirect_uri=http://example.com/step2&display=popup')" />
But when the user logs in via Facebook, the popup just displays the Facebook.com homepage. I'd like for the popup to authenticate the user and go away so that I can start retrieving user data from the graph api.
Is there a better / easier way to do this? Simple examples are appreciated.
Thank you.
oauth2 in facebook involves two steps, call authorize to get code, then call access_token to get token.
One way to deal with the pop login:
open login url in new window just like you did,when the facebook redirects back to your url in the popup, you set the cookie either through server side code or using javascript to capture url query parameter, when page is loaded in the popup, close the window immediately window.close.
On your main page, after your window.open code, add JavaScript code to detect if popup is closed and capture the cookie:
var signinWin;
$('#FacebookBtn').click(function () {
var pos = screenCenterPos(800, 500);
signinWin = window.open("[URL]", "SignIn", "width=780,height=410,toolbar=0,scrollbars=0,status=0,resizable=0,location=0,menuBar=0,left=" + pos.x + ",top=" + pos.y);
setTimeout(CheckLoginStatus, 2000);
signinWin.focus();
return false;
});
function CheckLoginStatus() {
if (signinWin.closed) {
$('#UserInfo').text($.cookie("some_cookie"));
}
else setTimeout(CheckLoginStatus, 1000);
}
Why not simply...
function authorizeAppInPopup() {
FB.login(function(response) {
if (response.authResponse) {
// User authorized app
} else {
// User cancelled login or did not fully authorize
}
}, {scope: 'publish_stream'});
}
??? : ]
https://developers.facebook.com/docs/reference/javascript/FB.login/
Checkout this article: Create Facebook PopUp Authentication Window using PHP and javascript for customize popup authentication.
It might be a good idea to do both a callback function from the Child window as Avner says as well as a timer that watches for the window to be closed. That way if the Child window is closed without a specific action you can take appropriate action on the Parent window.
**On Child**
// Set oAuthToken from server side when it comes back from authenticating
// and you have the token on the server side.
var oAuthToken = "";
oAuthToken = "--STRING INSERTED BY SERVER SIDE CODE--";
window.opener.pbFromPopup(oAuthToken);
**On Parent :**
function CheckLoginStatus() {
if (authWindow.closed) {
// Handle error if authentication window is closed
// without any action on Allow or Deny
alert("window closed");
//location.href = "errorPage.aspx?error=authwinclosed;
}
else setTimeout(CheckLoginStatus, 1000);
}
function pbFromPopup(token) {
// Function called from child window,
// token is passed back from child
authWindow.close();
// Put token in a hidden form field and submit the form to pass
// it back to the server
$("#authToken").val(token);
$("#form1").submit();
}