Is a user logged in, and a list of logged in users

Topics: Core, Writing modules
Mar 5, 2012 at 5:21 AM

Hi:

I am developing a website with a social aspect to it.

I have users id, and consiquently name, what I'd like to be able to do is determine whether they are currently logged in to the site. Is there a way to do this, als is a list of currently logged in users available.

Can I determine the last loggin/out time of a user, or is this something I would need to add?

Cheers

Sean.

Developer
Mar 5, 2012 at 8:23 PM
Edited Mar 5, 2012 at 8:25 PM

I think that's something you need to add yourself. In essence, what you'd want to do is create a new part, say MembershipPart, which has a LastActiveAt property of type DateTime. Next, attach that part to the User content type using a Migrations class (or using an ActivatingFilter).

Next, you create a filter that executes on each request. This filter will get the currently authenticated user (using IAuthenticationService), and set the LastActiveAt property of the MembershipPart:

using System;
using System.Web.Mvc;
using Orchard.ContentManagement;
using Orchard.Mvc.Filters;
using Orchard.Security;

namespace MyModule.Filters {
    public class OnlineUserFilter : FilterProvider, IActionFilter {
        private readonly IAuthenticationService _authenticationService;

        public OnlineUserFilter(IAuthenticationService authenticationService) {
            _authenticationService = authenticationService;
        }

        public void OnActionExecuting(ActionExecutingContext filterContext) {
            var user = _authenticationService.GetAuthenticatedUser();

            user.As<MembershipPart>().LastActiveAt = DateTime.UtcNow;
        }

        public void OnActionExecuted(ActionExecutedContext filterContext) {}
    }
}

Next, whenever you want a list of online users, you simply select all the users that have been active in the last, say 15, minutes:

public IEnumerable<IUser> GetOnlineUsers() {
            var thresholdTime = DateTime.UtcNow.AddMinutes(-15);
            return _contentManager.Query<MembershipPart, MembershipPartRecord>().Where(record => record.LastActiveAt >= thresholdTime).List();
        }

 

Mar 5, 2012 at 10:21 PM

Hi:

Thanks for that, If I want to log anybody out who’s session hasn’t been active for say 90 mins, would you use a scheduled task for that?

Cheers

Sean.

From: sfmskywalker [email removed]
Sent: 05 March 2012 21:24
To: Sean Farrow
Subject: Re: Is a user logged in, and a list of logged in users [orchard:347290]

From: sfmskywalker

I think that's something you need to add yourself. In essence, what you'd want to do is create a new part, say MembershipPart, which has a LastActiveAt property of type DateTime. Next, attach that part to the User content type using a Migrations class (or using an ActivatingFilter).

Next, you create a filter that executes on each request. This filter will get the currently authenticated user (using IAuthenticationService), and set the LastActiveAt property of the MembershipPart:

using System;
using System.Web.Mvc;
using Orchard.ContentManagement;
using Orchard.Mvc.Filters;
using Orchard.Security;
 
namespace Orchard.Widgets.Filters {
    public class OnlineUserFilter : FilterProvider, IActionFilter {
        private readonly IAuthenticationService _authenticationService;
 
        public OnlineUserFilter(IAuthenticationService authenticationService) {
            _authenticationService = authenticationService;
        }
 
        public void OnActionExecuting(ActionExecutingContext filterContext) {
            var user = _authenticationService.GetAuthenticatedUser();
 
            user.As<MembershipPart>().LastActiveAt = DateTime.UtcNow;
        }
 
        public void OnActionExecuted(ActionExecutedContext filterContext) {}
    }
}
 
 

Next, whenever you want a list of online users, you simply select all the users that have been active in the last, say 15, minutes:

public IEnumerable<IUser> GetOnlineUsers() {
            var thresholdTime = DateTime.UtcNow.AddMinutes(-15);
            return _contentManager.Query<MembershipPart, MembershipPartRecord>().Where(record => record.LastActiveAt >= thresholdTime).List();
        }

Developer
Mar 5, 2012 at 10:35 PM

I guess you could use a Background Task using Orchard to mark users as being "logged out". Alternatively, you could write could in the same filter that updates the LastActiveAt property that checks whether 90 minutes has passed. If so, you simply sign out the user using IAuthenticationService.

Another approach that requires no code at all is simply configuring Forms Authentication from web.config to have user sessions expire after 90 minutes (although that would set the same timeout value to site admins, but that might not be an issue)

Mar 7, 2012 at 2:35 AM

Hi:

The site admins being logged out isn’t an issue. Is thee any way however I can intercept events in the httpApplication class. Is it safe for the orchard httpApplication class to implement IUserEvents and then add a session expired event to that event interface.

Also, correct me if I’m wrong, but I don’t think there’s a logged off event?

Cheers

Sean.

From: sfmskywalker [email removed]
Sent: 05 March 2012 23:35
To: Sean Farrow
Subject: Re: Is a user logged in, and a list of logged in users [orchard:347290]

From: sfmskywalker

I guess you could use a Background Task using Orchard to mark users as being "logged out". Alternatively, you could write could in the same filter that updates the LastActiveAt property that checks whether 90 minutes has passed. If so, you simply sign out the user using IAuthenticationService.

Another approach that requires no code at all is simply configuring Forms Authentication from web.config to have user sessions expire after 90 minutes (although that would set the same timeout value to site admins, but that might not be an issue)