I am trying to create a chat application in PHP using AJAX and javascript. When I try to post messages in the same browser window, the messages are posted and displayed properly. But when I opened another window and tried to send message to the first window user, it does it, but when next time I post message from window 1, it posts as if it is posting from window 2 user. I am using sessions to record username, and I believe that everytime a window is loaded, the value in the session variable of user changes and it affects the behaviour of the application in all the windows. ie, username stored as session variable in window 1 is overridden by username in window 2, because both are accessing the same piece of code. And everytime AJAX tries to get new messages from database, it gets for a different user when a new window is loaded.
I was wondering if this could be solved by Multithreading, or if there is any other way to solve this. Do chat applications require Multithreading always? It is quite confusing to me. Please help.
If you want to simulate two different users who should have different sessions who are chatting with each other you can open two different browsers (for example Internet Explorer and Firefox) and log in with one user on each browser. Then the session is not shared.
As far as i know different browser windows in same browser share sessions so the later login will overwrite the first login.
Related
I have made a website that enables users to create their own widgets and place them on their own websites. I want users of those websites to be able to log in to these widgets using Twitter, Facebook and Google. I have 99% of the process in place, but the remaining 1% is my stumbling block. The process I have implemented is as follows:
User creates a widget on my site (mysite.com)
User places some javascript on their own website (example.com) to embed the widget
The user of a widget clicks "Log in with Twitter"
A new window is opened (using window.open) which loads mysite.com/auth/twitter, redirecting them through the oAuth flow on twitter.com
All being well, the user gets redirected back to mysite.com/auth/twitter/callback in the new window and I store the user's details in the database on mysite.com.
At this point, the newly-created User ID should be passed back to the main window in which the widget is embedded. But, as far as I can tell, there is no way to do so because because window.opener in the new window is null (due to the redirects that have happened). Nor do I have a reference from the main window to the new window, also due to the redirects.
I have tried window.postMessage from the new window to the main window, directly accessing functions and variables in the new window from the main window, all to no avail. There is seemingly no way to reference any data or properties from either window.
Is there anything else I can try or do I have to implement the process without a new window somehow?
If it matters, mysite.com is built in Laravel and the social authentication process uses Socialite.
Any help is appreciated!
I have tried window.postMessage from the new window to the main window
postMessage works cross-domain, but you must in that case specify the second parameter (targetOrigin).
Taking into account your clarifications regarding how the widget is embedded, you are fairly limited in regards to communication options as you saw.
Since your child window now has no way to communicate with the parent, being without a window.opener reference and on a different domain, you could rely on the parent and have it track the child window progress like suggested here : https://stackoverflow.com/a/18804255/18706075
Also, not to be insistent on the iframe approach, but you could also add an invisible iframe opened to mysite.com. That way, the pop-up window that ends up on mysite.com has many options to make data available to the iframe on the same domain, and the guest iframe can easily communicate with the host window as I originally suggested :
Host listens to the message event
window.addEventListener("message", myMessageHandler);
Guest iframe notifies the host.
window.top.postMessage({authenticationResult: "whatever_value"}, 'http://example.com');
I couldn’t find a “proper” way to do this, so what I ended up doing was generating a unique code and passing that to the new window. This code gets stored in my database and updated with the ID of the user upon completion of the oAuth process. The main window uses setInterval to check for the existence of a user ID against the unique code every couple of seconds.
POPUPS AND IFRAME REDIRECTS
I would have a look at the oidc-client library, which used to do similar things. See the code in PopupWindow and the way that a named window object is used before the redirect and then used on the response. The OAuth state parameter was used to correlate the request and response:
// Before navigating
window["popupCallback_" + params.id] = this._callback.bind(this);
// Notify opener upon return
var name = "popupCallback_" + data.state;
var callback = window.opener[name];
callback(url, keepOpen);
The library also performed some interesting iframe navigation if you look at the IFrameWindow and IFrameNavigator classes. Using iframes can be permissioned with your own authorization server, but will not work with Google or Twitter due to clickjacking protections.
BROWSER RESTRICTIONS
One of the reasons why the above library is inactive is browser restrictions on content from third party sites, which impacts some of the browser OpenID Connect behaviour.
Your widgets will be treated in a hostile manner by browsers, who will apply the same restrictions as they do on third party ads that try to track users across sites.
In particular, if your widget gets data by calling mysite.com with an HTTP-only cookie, this will be considered a third party cookie and dropped by the browser. Access tokens can work, but they are not considered the browser current best security practice.
MAIN WINDOW REDIRECTS
If you can't get popups to work, consider redirecting on the main window, which will work best from a browser restrictions viewpoint. A main window redirect serves as a user gesture so that any login cookies from Google etc are not dropped. Your flow might work like this, though it requires a design based on access tokens:
Customer page loads at example.com
Widget loads in an iframe at mysite.com and renders content that prompts the user to click a button to authenticate
When the button is clicked, the widget saves the parent URL in session storage, then redirects the parent window to Google, with a mysite com redirect URI
Main window at mysite.com conpletes the login, saves an access token to session storage, then redirects back to the stored parent URL
Customer page loads again at example.com
Widget loads again in an iframe at mysite.com and this time can get an access token from session storage to use for data access
From a user experience viewpoint, the user signs in to the main app initially, then once more to the widget as a separate provider. The impact on the host app is a bit like refreshing the page, which it will already cope with.
FUTURE
The FedCM initiative is aiming to solve this type of cross domain browser identity problem in a future facing way. It will not be ready any time soon, but it is worth reading their docs to identify potential issues with your own solution.
My web site uses magic links for login, however, I have a problem on mobile (not sure about Android - haven't tried yet, but the problem exists at least on iOS): when a user receives the email say in the GMail app, the link opens in the embedded browser, meaning that cookies will not be passed to the "real" browser.
Is there a way to ensure the link in the email opens in the real system browser and therefore cookies are stored permanently?
(Essentially browser session isolation on iOS breaks a lot of things on the Internet, so surely there is a workaround?)
After some research: no, it is not possible to detect you are in an embedded browser, neither is it possible to enforce opening a link in the system one. Makes sense from security point of view.
However, I was asking the wrong question. The problem of a magic link login is solved differently: when starting a login process you can set a session cookie and create an associated DB record for it, marking it as blocked, i.e. not logged in.
At next step, when the magic link is opened in whatever browser you unblock the session in the DB. At this stage you can replace the login cookie with a real one, e.g. JWT, or continue using it as your main auth token.
If the user then returns to the real browser, you check the login cookie and act accordingly, keeping in mind that it may not be the browser where they validated the magic link. At this stage you can, again, replace the login cookie with your real auth cookie knowing that the session has been validated already.
I'm not entirely sure this is 100% safe, need to think about it more but at first glance it does look safe and seems to be pretty much the only way of handling magic links on mobile.
I'm building a chat application with some php, mysql, nodejs, socketio.
I want to allow users to be logged in from nomatterwhat number devices. Like eg. Facebook where it doesn't matter which screen you're looking at. They all reflect the latest changes.
Tested it right now and it works that way. If i open the notifidations the number dissappears on the same page on different devices.
My guess -and started building with that iedea in mind – was that a room is created for each user when a user logs in the first time and any following login from the same user is also added to that room so the changes can easily be broadcasted to the room.
All browsers are aware off the multiple logins because i send a soclet-message to the room setting a variable - multilogin- so that it knows that there are more.
Also needed to see when a user clicks on the logout-buttons it send that information along.
If it is the only one logged in it should kill the session set the user offline.
Actions performed on one device, broadcasts it to the other members in the room etc.
Seems logical?
It works so far but i'm uncertain about the session part of this setup.
The logic in php -inherited from the origanal build of the chat – checks the user logging in to see if the user is already logged in and if so, it destroys the existing session first and then sends a loggout command -which i prevent now when the multilogin parameter is send along- to the other browser.
My question now is, what could be a logical approach towards the sessions?
I was playing with some ideas in my head and then i thought, let's look on the internet about the subject.
An idea could be that only the first loggin in gets the session created and is shared by sending the id to the others so they can be identified as being the same user.
Would that be an approach that one would suggest?
Found a simple solution by letting each device with same user that logs in getting a new sessionid which is send to the others (socket message to room) so their sessionid becomes the same to authenticate themselves to the server. Session id is save enough for that purpose.
I had a specific questin about angularjs with websocket. I currently have an application that utilizes a websocket to communicate with a server, this is all nice and dandy - and when I move around pages in angular the websocket persists throughout all of the routes which is neat. Unfortunately the problem is that if the user refreshes the page (for some dumb reason), the websocket disconnects. I was wondering what the best method of handling this is. Should I just have an alert when the user tries to refresh, can I somehow detect that the websocket is closed when the page is refreshed and start a new one? I'm just wondering what the best practice for something like this is.
Thanks
There is nothing you can do, if the user refreshes, it is like restarting an application, all the bootstrapping happens again and connections are created again.
You can use javascript:onbeforeunload to warn the user that if refreshes or leaves he will lose the connection. But your users will hate your for that, it is very annoying.
Consider as well, that the user may open several tabs.
Starting a new connection is the best way. Just make sure that the user can somehow recover his context. If there is a different context per tab, then you will have to put a connectionID parameter in the URL to persist it through refreshes, and if the context is per user session, then a cookie with the session ID will do.
I am using socket.io in my node.js application to give real time experience to my users. But due to leak of my experience with socket.io, I have some doubt with browser tab management. Let me explain first.
My website does not allowed login to user from multipul browser at a time. means If someone login from one browser, and then try to login from another browser, I have to kill previous login session. Means my socket.io emit messages to previous browser's all tab for logout, but my second browser's all tab should not get message for logout. How Do I do this?
Another question is I want to count distinct logged in users for my deshboard. But with multipul tabs, count is showing wrong figger. (eg. Single user accessing website from single browser but from 2 or more tabs, on server, socket client is showing each connection for tab, Here I need just one count. How Do I get it?
If some one has example/sample regarding above user case, please share it, so new coumer will gets help from it.
thanks