How do you logout a user from the server in PHP?

I want to create a customisation that logs users out after a certain time of inactivity since closing Sugar in their browser (e.g. log out at night). I need this separate from Oauth token lifetimes so that APIs and the Outlook Plugin can still be configured to never log off.

I'm trying to find a way to log the current user out in Sugar using PHP. I've looked at these files and tried their logout implementations with appropriate adjustments in a custom logic hook and a custom entry point, but none have worked:

  • clients/base/api/OAuth2Api.php
  • modules/Users/Logout.php

Do you know of any method of logging out a user without using the browser?

  • Hi

    check out this blog post: Session duration on Sugar 7 | Enrico Simonetti [dot com]  

    From that post you could try removing entries from oauth_tokens table.

    HTH

  • Thanks, that's a very helpful article in general!

    But it even says that just the table won't be enough:

    If the entries are only removed from the database table, it will only fail to re-generate the next token as soon as the current one expires, but it will not logout the users right away.

    And I believe there must be a clean method of logging a user out already available, since Sugar does that through the API and in other places. It's weird though that the same code doesn't work in an entry point or a logic hook.

  • Hi again

    Yes, you're right about that bit from the blog post. Simply deleting the entry from the table will not be enough. One thing that's not exactly clear to me about your use case is if the users will still be logged in? For example, will the application still be open in their browser? Or will they close the browser without bothering to log out?

    As you're probably aware the process of logging out of the application eventually hits the oauth2/logout endpoint but before doing so it's doing some clean up on the client side. I had a look on a 7.9.2 instance I have locally and as far as I can tell the first JS function that gets triggered when you logout is in the sidecar/src/core/router.js in the logout function. If you follow the flow from there you'll see that this will delegate to the logout function in sidecar/src/app.js. This function is triggering the app:logout event which has a few listeners scattered around. Without rambling on much further I don't think you can trigger a full logout strictly from the server via PHP. 

  • Hi Artis Plocins,

    If you need a user to be logged out after X minutes since login (independently from user activity), you can achieve so by setting the configuration option as stated on the blog post:

    $sugar_config['oauth2']['max_session_lifetime'] = <seconds>;

    Alternatively, if you need an idle logout triggered client side, I did a POC for a similar use case quite some time ago that you could have a look at as a starting point, and see if it still works. The POC would only apply to browser based inactivity (not mobile or plugins) and it is i initiated client side. The code can be found here: GitHub - esimonetti/SugarIdleLogout: Idle based automatic logout from web browser ui 

    Also, do remember that this could cause issues if the users have unsaved work on their browsers and the system logs them out.

    As a disclaimer, as usual please note that any of the code changes samples provided are "as is" and it would be your responsibility to maintain and support.

    --

    Enrico Simonetti

    Sugar veteran (from 2007)

    www.naonis.tech


    Feel free to reach out for consulting regarding:

    • API Integration and Automation Services
    • Sugar Architecture
    • Sugar Performance Optimisation
    • Sugar Consulting, Best Practices and Technical Training
    • AWS and Sugar Technical Help
    • CTO-as-a-service
    • Solutions-as-a-service
    • and more!

    All active SugarCRM certifications

    Actively working remotely with customers based in APAC and in the United States

  • Hi,

    Thank you for the link, though I've already used a jQuery idle timeout implementation from the Sugar developer blog for the same purpose.

    What I need is to have all users who have closed their browser for 12 hours to get logged out, but services like the Outlook plugin to stay logged in practically forever.

    So in that case, I believe, the max_session_lifetime setting needs to be an extremely high number to prevent the  Outlook plugin from logging out.

    At the moment I am l trying to find a way to end sessions on the server for specific users in Sugar.
    I decided to use the Trackers module with a scheduled task to check the time since the last activity of a user and removing their refresh token record from the oauth_tokens table. That's working well, but just as you've described in your post - the user gets logged out only if Sugar is not open in their browser when the next refresh token request comes, which is not what I can rely on.

    The method SugarApplication::endSession() seems to apply only to the current session, regardless of the user even if I switch the current user to any other. Either that or I'm not sure about it.

  • Hi Artis Plocins,

    The short answer is: unfortunately I do not think you can do what you are trying to do, the way you are trying to.

    The reason is that the session is normally a cookie that sits on the client side, and has a matching file (by default in PHP, but it can be stored somewhere else like redis, memcached etc.) on the server side. PHP with sessions pairs them up and gives available to the specific "session" the correct information.

    From the server side initiating point of view, I am pretty sure you do not know who's who. You could in theory, as I think the access token is also the session id, but then you end up having to delete manually the matching files on the file system (if using the default PHP) and that would be really really ugly for multiple reasons. I would really discourage even attempting this all together.

    One thing that I do not understand is why the idle plugin would not work in your case. A closed browser should be treated as an idle browser, correct? It might just require some small tweaks on your current code then, that will trigger a logout immediately upon reopening of an idle browser?

    You could also lower the refresh token to < 12 hours, so that when a user does not use that refresh token for 12 hours (as the browser is closed), and the access token expires in the meantime, the client won't be able to obtain a new one using the refresh token.

    Alternatively you could try leveraging the session garbage collector and see if it works for your case and does not create other problems? (PHP: session_gc - Manual )

    Regarding Outlook, I do not think max_session_lifetime has any effect there, as the credentials in theory are available for the systems to use, to obtain a new token whenever the old one expires.

    Hope this helps you move forward

    Cheers

    --

    Enrico Simonetti

    Sugar veteran (from 2007)

    www.naonis.tech


    Feel free to reach out for consulting regarding:

    • API Integration and Automation Services
    • Sugar Architecture
    • Sugar Performance Optimisation
    • Sugar Consulting, Best Practices and Technical Training
    • AWS and Sugar Technical Help
    • CTO-as-a-service
    • Solutions-as-a-service
    • and more!

    All active SugarCRM certifications

    Actively working remotely with customers based in APAC and in the United States

  • Hi Artis Plocins

    Deleting entries from the oauth_tokens table will not just cause the regeneration of the next token to fail as soon as the current one expires.

    It will also logout the users, however not right away, but within 2 min: The oauth_tokens table is checked every 2 mins if the refresh token still exists. If not, the access token is set to NULL and the session is logged out.

    See include/SugarOAuth2/SugarOAuth2Storage.php

    ...

    const TOKEN_CHECK_TIME = 120;

    ...

    public function getAccessToken($oauth_token)

  • Hi Enrico,

    I just managed to do it.

    There may be other ways of acquiring user session ID's (AKA access tokens), but using the Tracker module's tracker_sessions table seems a good way.

    You can log off any and all users immediately by using SugarOAuth2Server to unset the refresh token and using PHP's session functions to juggle user sessions and destroy them. This session code helps: PHP: session_destroy - Manual.

  • Would it be an option if you create a Scheduler at night and use SugarRest API to login to each account (assuming you know the credentials)? I believe this would log the users out.