This forum is archived. Posts are preserved for historical reference. For current help, join us on Discord.

Automatic logout all userspice pages when one of them is logged out

In UserSpice 4.3 and Below · Started by Angel on 2016-09-23 1:32 pm · 66965 views · 28 replies

Hi UserSpice developers,

I'm currently testing my implementation of userspice on my project. One thing I notice is that when user opens more than 1 page of userspice in the browser, and then logout in one of the pages, the other pages still remains active unless you refresh the page. I'm thinking if there is a way to add an automatic logout on all UserSpice pages when the user logout in one of them? May be some changes in the navigation.php or header.php or ini.php so that all userspice pages would have this function?

Thanks for all your effort in maintaining this website!

Best,
Angel
I can definitely look into this but as a rule each Tab in a browser is its own unique instance. The reason for this is to stop one tab from stealing information from another tab... we may be able to for some kind of check of the system session information every time a page loads. I will take a look at that.
So when you say "remain active" do you mean it still shows as Logged In until they try to navigate elsewhere? As soon as they try any other interaction, it should then show them as logged out. That is sort of by design, because right now, virtually all the functionality is server side, there isn't really any client side (i.e. JavaScript) in the UserSpice code, and that's the only way I can think of to "force" a logout of all pages when it is performed in a separate tab.

That is something that could be done...implement a JavaScript watch dog that checks every 30 seconds if the session is still valid or not. Perhaps someone has a better idea than this what would be more responsive. I'm not sure how we would do that server side. The downside to the JS implementation is that it could be disabled, though that wouldn't matter that much since users would be logged out on their next action in the other pages.

Have I interpreted your observation correctly?
You are absolute right with what I meant. I'm trying to release my project along with UserSpice to test again right now. One of the feature that needs to be done is the "automatic logout detection" thing. I think the "Javascript watch dog" idea would very likely work. Do you have any suggestions as to how to do that?

Thanks
Angel
One important reason to add this automatic logout detection feature is that I'm adding function level access control to pages in my project. I mean, right now userspice controls user access to the page level, which means based on his/her authorization access, the user can either access the page or not. But some of my use cases would be to grant the user read access to a page but not allowing them to edit anything. I already have this function level access control done by adding an additional permission level check on my pages. But to make sure that no one can edit anything without the right permission, it is important to detect whether this user is logged out on other tabs of the browser. And I think it might also be a potential feature that could make userspice more secure.
To help me understand the use case, if a user logs out in one tab, then they would not be able to do anything but view the other pages that are open. If they tried to make a change and submit a form or something like that, they will be prevented from doing so and be required to login again.

From a real security standpoint, client side JavaScript cannot be relied on, because a user could simply disable JS processing thereby adding no more security.

So that brings us back to how this could be implemented on server side with the technologies available on most web servers.

What types of edits are you trying to prevent? are these forms being submitted, or access to a specific file?
That would be one of the use cases. Another one would be some user might not even have read access to the page, but were still able to view it if the page is not signed out for the last user.

I'm outputing the form to a separate php file to update database. and yeah I think to prevent editing submission, I can add the permission check on my submit php file. But it would still be important to have this automatic logout detection, so that no one could read the page if the user is logged out.
Well, that will be tough with only client side operations. Once the data reaches the client and displayed in the browser, it is out of the hands of the server and the server can't do anything about it. The only thing the server could do is control access on the NEXT request where the server is once again involved in the transaction.

Even things like banking sites are at the mercy of the users browser. In that case, the session gets expired on the server side, and on the client side the pages are served with an expiry in the cache so they can't be displayed after the browser is closed.

So to me, it would appear that you could do what banks or other sides do, and run a JavaScript check and logout, but that can be disabled...just as a warning.
Well I guess the javascript check and logout method is still better than not having any check. And our users are mechanical engineers, I don't think they would want to disable javascript when they are opening the page.

I just googled but only found some javascript to timeout a user, instead of constantly checking the session. would you mind be more specific as to how to do the javascript check and logout?
Okay, just wanted to be sure that part was understood.

I can take a crack at it, I'm not sure how long it would take me though.
Yeah that was understood. Thank you so much!
Okay, I just about have something, but it won't be the prettiest of solutions I'm sure, but it would work as a starting point that you could refine.

*edit* I do have something that will work, I just need to write up the instructions for you.
Awesome. Thank you so much!

Best,
Angel
So, here is the javascript you can paste in the footer with the rest of the script tags (or wherever it will get executed on everypage...maybe you have a .js file you are already including or something):

http://pastebin.com/CiqVKuW0

And here is a PHP file you need to create and call users/helpers/logoutcheck.php (you can change the name, you can see the reference in the JavaScript code...just make sure they match). Also, you can set the check interval by replacing 5000 with something else (that is the time interval in milliseconds....5000 milliseconds = 5 seconds.

http://pastebin.com/9D5DKkiB

In your code you will need to change US_URL_ROOT to $us_url_root (I'm working on UserSpice 5 code base so that's why it is different).

Lastly, you need to create a hidden div or span that contains this text (again you can change it as you want, as long as the references all match) "Not Logged In" when $user->isLoggedIn()==False, and displays "Logged In" when the user is logged in. The HTML ID of this div or span needs to be set to "loginstatus" so the jQuery can find the right text and pass it to the PHP page.

Now, I'm not a JavaScript person, but this is how I solved the problem. The javascript function runs every 5 seconds, and when it runs, it executes the logoutcheck.php file with the string contents of the "loginstatus" hidden div. Inside the PHP file, it checks if $user->isLoggedIn() is false AND the string does not say "Not Logged In". If this is the situation, it means the user session has ended on another page, but the current page still says the user is "Logged In". This means the state of the page does not match the $user session state and it will run a redirect to the homepage ($us_url_root.'index.php'). Any other combination of states and it won't do anything.

This is a really crappy description and for that I apologize. See where you can get, and we can go from there.
Oh wow thanks for the detailed explanation! I'll give it a try now and let you know how it goes.

Thanks!
Angel :)
I will see about adding a more robust version for either 4.2 release or 5.0 release.
hi Brian,

I just added the js code at the bottom of header.php and created the logoutcheck.php in the helpers folder. The html div is also created with the following code in header.php:
<div id = "loginstatus" style = "display: none" >
<?php
if ($user->isLoggedIn()==False){
echo "Not Logged In";
}else{
echo "Logged In";
}
?>
</div>

I notice that when the javascript post data to logoutcheck.php, there is an error saying:
Access forbidden!

You don't have permission to access the requested object. It is either read-protected or not readable by the server.

If you think this is a server error, please contact the webmaster.

Error 403

Is there anything wrong with my implementation?

Thanks
Angel
Delete the .htaccess file (for now) that is in the users/helpers folder. That should make it work. There is probably a better place to put that file, but you can move it (and adjust the JS reference to it anytime you wish).
it works! thanks a lot!

an issue I see is that somehow my page gets refreshed every 5 seconds. Is that a supposed behavior?

In addition, I changed one phrase in your code to be:
$.post(<?=$us_url_root?>+"users/helpers/logoutcheck.php", {loginstatus:$("#loginstatus").text()},
instead of this:
$.post("users/helpers/logoutcheck.php", {loginstatus:$("#loginstatus").text()},

I noticed this because I had all my pages under usersc folder instead of users folder. so when I'm at my pages the setInterval function gets redirected to users/users/helpers/logoutcheck.php instead of users/helpers/logoutcheck.php. Please let me know if this is a proper fix.
I guess PHP would parse $us_url_root prior to displaying the page, so if it works for you, then that is just fine.

The page should only refresh in the case where the user is logged out, and that div doesn't say "Not Logged In". So it *should* only fire on the pages which meet that criteria, and shouldn't happen at all when a user is logged in.

Just to confirm, if you sign in, then open another tab for your userspice install, and then sign out of one of your tabs...the tab you didn't sign out of should be the only one that refreshes.

However, you are seeing each page reload and take you to the destination specified in the logoutcheck.php?
12Next ›