How can I obtain user's last active time when using Devise? - ruby-on-rails

Suppose Users are spending long time in the web-site.
How can I obtain user's last active time.
Last active time means the last timestamp of user who requested(accessed to the page. user even doesn't need to update or create new record) to app.
A User might have signed in about an hour ago. Then he's still web surfing in my web site.
I want the time of last request the user sent.
Is it possible?
Devise has current_sign_in_at but not last active time.

The way I would implement this is to add a last_active_at datetime column to the User model, then putting something in my controller:
class ApplicationController
before_filter :record_user_activity
private
def record_user_activity
if current_user
current_user.touch :last_active_at
end
end
end

Related

find and terminate all active sessions by user_id

I'm using cookie based sessions on a Rails 6 app with the following setup:
Rails.application.config.action_dispatch.cookies_serializer = :marshal
Rails.application.config.session_store :cookie_store, expire_after: 14.days
After a user changes his password I'd like to terminate all his active sessions, which could be in other browsers and/or devices. Something like this:
ActionDispatch::Session::CookieStore.where(user_id: session[:user_id]).destroy_all
Only those aren't really valid methods for CookieStore. Any idea how to accomplish this?
Unfortunately, you cannot accomplish this via sessions no matter the way of session storage.
To be able to do this, you have to keep the list of active logins on the server in separate DB table and delete those records instead eg:
You create new table eg logins with columns user_id and token. Every time user logs in, you will create new record in this table and then you save user_id and token to the session:
def login
# ...
# user authorization code
# ...
login = user.logins.create(token: SecureRandom.uuid)
session[:user_id] = login.user_id
session[:user_token] = login.token
end
and every time you are loading user from the session you have to do two steps:
find user by ID
check user_token validity
def authorized_user
#authorized_user ||= begin
login = Login.find_by(user_id: session[:user_id], token: session[:user_token])
return if login.blank?
login.user
end
end
And now, every time you want to logout user you just have to remove corresponding record from logins table.
In your case you want to logout user from all other devices, only thing you need to do is to execute following code:
authorized_user.logins.where.not(token: session[:user_token]).delete_all
and you are done.
Of course this is just a simple example, you also can hash or encrypt tokens, so they are not directly readable or you can add expiration date and automatically log out users when the date is exceeded, etc..

"User last online" at <time> using devise?

Is there any easy/native way to display when a user was last online on their profile page using a standard rails app using devise for authentication?
The closest I can get is
<%= #user.current_sign_in_at.to_s %>
This shows the last time a sign in occurred (which could differ significantly from the last time the user checked the site - i.e the last time they were 'online' so to speak). For example, I'd like to show a little green light if the user was using the site anytime in the last 90 seconds, but that won't be accurate if using the time of their last sign in.
Add a column in a users table last_seen_at & update it every time using touch.
class ApplicationController
before_action :record_last_seen_at
private
def record_last_seen_at
if current_user
current_user.touch :last_seen_at
end
end
end

Increment a users login count

I have an existing application where a user can log in etc. This does not use devise works fine. I wanted to create a feature that counts the users login attempts and as such increments this by one each time they log in. I am aware of active record and increment as i have put below.
def increment_login_count!
update_attribute(:login_count, login_count + 1)
end
Could anyone offer any other advice as to how to do this logic. I wanted to start with a controller spec and work from this but i am a little unsure.
Try this
def increment_login_count
increment! :login_count
end
And you can call this method whenever a new session is created for the user
You can refer to docs for more information

How to handle the expiration of login cookies if a user is inactive for more than a set time using Ruby on Rails?

I am trying to manage the login session of users that navigate in my RoR3 application.
I set a cookie when they sign in and I would like that their authentication expires after a few minutes of inactivity, for example 15 minutes.
How to achieve that?
This doesn't directly answer your question, but I strongly suggest using something like Devise for authentication instead of rolling your own.
Devise provides a timeoutable configuration flag, as well as a timeout value covering how long user sessions can be inactive before being logged out.
You could setup a property in your session. Something like
session[:expire_time] = 15.minutes.since
Then, in your applicationController you can check if your user has been away enough time to be logged out, if not then you renew his expiration time, something like:
class ApplicationController < ActionController::Base
before_filter :check_expire
def check_expire
if session[:expire_time] and session[:expire_time] < Time.now
#your code to logout the user
else
session[:expire_time] = 15.minutes.since
end
return true
end
end
You can also set the expiration time of the cookie that sets their session. In your configuration :
env["rack.session.options"][:expire_after] = 15.minutes
This works perfectly for the use case you described, because it will be reset every time the server responds, but it gives you a little less control.
Here's a good article about it :
http://augustl.com/blog/2010/dynamic_session_expiration_time_in_rails_3

Finding last active time for logged in user

I am using ruby on rails session to store a user cookie to keep them logged in, so I can't just update a last_seen column after they login. I'm trying to figure out the best way to find out if a user has been active in the last day. This is what I have so far but I'm wondering if there's a better way:
class ApplicationController
before_filter :update_last_seen
private
def update_last_seen
if (DateTime.now - 1.day) < current_user.last_seen
current_user.last_seen = DateTime.now
current_user.save
end
end
end
The problem with this is that it is going to get called with every request. Is there any way to avoid this? Does the session cookie get updated somehow when a user is active?
No, that is exactly how you should go about it. before_filters are a great way to keep track of things like that, and are how authlogic implements it's authentication system as well. There's no way to do processing on one request "per day". If you use Authlogic as your authentication method, it has last-login time built in. You can see an example of it here.

Resources