auto-session-timeout
auto-session-timeout copied to clipboard
this gem is not compatible with turbolinks
When use turbolinks, consider clicking the 'next page' button of a list for several times, the trigger of post '/active' will repeat for this times. e.g. I auto_session_timeout_js frequency: 120
, and then click 'next page' for 5 times, then every 120 seconds will post to /action
for 5 times. That's caused by write the codes in body. The correct way to do is wrapping the codes in $('document').on('turbolinks:load', function(){})
.
@killernova you should be able to add an ignore attribute for turbolinks when https://github.com/pelargir/auto-session-timeout/pull/18 is merged in, please have a look at the added test case
@emilos Yes, I've noticed this PR many days ago, but I've written some codes to replace the auto_session_timeout_js
method to make the gem work with turbolinks before this pr posted. I'll try it another day with the new method. Thanks.
@killernova #18 has been merged. Does that fix your problem?
I can confirm this is still a problem when Turbolinks is enabled. Replicated by logging in and clicking a few times. A request to /active
is trigger per click as outlined in the log output below when the browser is sitting idle:
Started GET "/active" for 127.0.0.1 at 2019-01-21 13:28:48 +0000
Started GET "/active" for 127.0.0.1 at 2019-01-21 13:29:16 +0000
Started GET "/active" for 127.0.0.1 at 2019-01-21 13:29:37 +0000
Started GET "/active" for 127.0.0.1 at 2019-01-21 13:29:49 +0000
Started GET "/active" for 127.0.0.1 at 2019-01-21 13:29:50 +0000
Started GET "/active" for 127.0.0.1 at 2019-01-21 13:30:17 +0000
Started GET "/active" for 127.0.0.1 at 2019-01-21 13:30:38 +0000
Started GET "/active" for 127.0.0.1 at 2019-01-21 13:30:50 +0000
Started GET "/active" for 127.0.0.1 at 2019-01-21 13:31:19 +0000
Started GET "/active" for 127.0.0.1 at 2019-01-21 13:31:39 +0000
Started GET "/active" for 127.0.0.1 at 2019-01-21 13:31:52 +0000
Started GET "/active" for 127.0.0.1 at 2019-01-21 13:32:19 +0000
Started GET "/active" for 127.0.0.1 at 2019-01-21 13:32:40 +0000
Started GET "/active" for 127.0.0.1 at 2019-01-21 13:32:53 +0000
I'll try reproducing this when I have time. If anyone wants to submit a PR fix in the meantime, please do.
I was able to reproduce this problem and am working on a fix.
If someone else has this problem too, this may help with Turbo and Stimulus.
On every page change, stimulus calls the disconnect function, where the already running function is stopped.
Important: Do not use auto_session_timeout_js
at the same time! Remove auto_session_timeout_js
from your view if already inserted.
rails g stimulus AutoSessionTimeout
Content of app/javascript/controllers/auto_session_timeout_controller.js:
import { Controller } from "@hotwired/stimulus"
// Connects to data-controller="auto-session-timeout"
export default class extends Controller {
initialize() {
this.intervalId = 0;
this.frequency = Number(this.element.dataset.astFrequency) || 60;
this.active_path = String(this.element.dataset.astActivePath)
this.timeout_path = String(this.element.dataset.astTimeoutPath)
super.initialize();
}
connect() {
if (this.active_path === 'undefined') {
console.log('auto-session-timeout message:')
console.log('ast-active-path is not defined - value: ' + this.active_path);
return;
}
if (this.timeout_path === 'undefined') {
console.log('auto-session-timeout message:')
console.log('ast-timeout-path is not defined - value: ' + this.timeout_path);
return;
}
this.intervalId = setInterval(this.check_timeout.bind(this), (this.frequency * 1000));
}
disconnect() {
clearInterval(this.intervalId);
}
check_timeout() {
const timeout_path = this.timeout_path
const request = new XMLHttpRequest();
request.onload = function(event) {
var status = event.target.status;
var response = event.target.response;
if (status === 200 && (response === false || response === 'false' || response === null)) {
window.location.href = timeout_path;
}
};
request.open('GET', this.active_path, true);
request.responseType = 'json';
request.send();
}
}
And in app/views/layouts/application.html.slim
:
[...]
- ast_values = user_signed_in? ? { data: { controller: 'auto-session-timeout', 'ast-frequency': 15, 'ast-active-path': "#{active_path}", 'ast-timeout-path': "#{timeout_path}" } } : {}
body *ast_values
[...]
Additionally, I had to adjust protect_from_forgery
in application-controller.rb
# Timeout sessions
auto_session_timeout
#has to be after auto_session_timeout so that prepend will not be overwritten.
protect_from_forgery with: :exception, prepend: true