Answers.Body: <p>You can check the remaining time in the session with JavaScript using Craft's <a href="https://craftcms.com/docs/4.x/dev/controller-actions.html#get-users-session-info" rel="noreferrer"><code>users/session-info</code> controller action</a>. This endpoint returns an object like this as a JSON response:</p>
  <pre class="lang-json prettyprint-override"><code>{
      &quot;isGuest&quot;: false,
      &quot;timeout&quot;: 10800,
      &quot;csrfTokenName&quot;: &quot;CRAFT_CSRF_TOKEN&quot;,
      &quot;csrfTokenValue&quot;: &quot;5bJjI1cYVEJ_QhYugiIOOY2CFVhy3RSFwJE96rRNZa6WhSMlL0j7O2e9pgexUgQBhRJ-cC8rjUBTZ8ASSarw3pBy__-buyTujPuxqIxG7OFK3hC0lRjFnw_2WOr3bf-QS7bSQjJONtlgUS7_SZBCSGCFUtZG5h99v2LqfganVeyJqrouOv765YUT-MTpvmlped6_hMM0ZAFULjAGKFN-0khCD-bTIxMfv1zx7fBSk_0DFPbH31RSHBGPThuFkmTTZWEy5yMYQx4TuiFqBaV0eZPE5qAWmsui2RzY7cnSyrol2oBzvCOE8y7yq26UPN-TCJ7xco_kegotVesBNF-oDsYOMhL8OJMWtnUxiQm7SE3KN6T9h9tBQ7e0lN1CorOejTAdDKKO&quot;,
      &quot;id&quot;: 1,
      &quot;uid&quot;: &quot;aaaaaaaa-1234-49a3-808f-449f78537bb5&quot;,
      &quot;username&quot;: &quot;user@example.com&quot;,
      &quot;email&quot;: &quot;user@example.com&quot;
  }
  </code></pre>
  <p>What you're interested in is the <code>timeout</code>, which is the number of seconds left until the current session expires. Note that this will always return <code>0</code> for guests, so this only works for logged-in users.</p>
  <p>You can get the session info like this:</p>
  <pre class="lang-js prettyprint-override"><code>const session = await fetch('/actions/users/session-info', {
      credentials: 'include',
      headers: { 'Accept': 'application/json' },
  }).then(res =&gt; res.json());
  </code></pre>
  <p>By default, the controller action will <em>extend</em> the current session, so the <code>timeout</code> will pretty much always be the same as your <code>userSessionDuration</code> setting. You could just call this method periodically and call it a day.</p>
  <p>If you want to be smart about it, you can also tell the controller action not to extend the current session by appending a URL parameter to the request: <code>/actions/users/session-info?dontExtendSession=1</code></p>
  <p>This will tell you the timeout of the current session without extending it. You can use this information to either set a timeout for when to warn the user, or just to extend the sessions (using the same controller action) automatically before the timeout is reached.</p>
  <p>The Control Panel does something similar, see <a href="https://github.com/craftcms/cms/blob/5.x/src/web/assets/cp/src/js/AuthManager.js" rel="noreferrer"><code>AuthManager.js</code></a> for inspiration.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-04-22T15:51:04.583Z
Answers.LastActivityDate: 2024-04-22T15:51:04.583Z
Answers.UserDisplayName: MoritzLost
Body: <p>I have a Craft CMS 4 with forms for logged-in users.</p>
  <p>Some users may keep certain pages open in their browsers.
  Sometimes, users submit the form while their session has expired (after one hour, in this case).</p>
  <p>This generates a validation error:</p>
  <pre><code>[web.ERROR] [yii\web\HttpException:400] Unable to verify your data submission.
  </code></pre>
  <p>How can we, probably via JavaScript on the client side:</p>
  <ul>
  <li>Display a message to the user when their session is about to expire</li>
  <li>Redirect the page to the login URL just before the session expires</li>
  </ul>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-04-22T15:04:51.720Z
Comments.Text: You're talking only about logged-in users, right? Because if I'm not mistaken, only login sessions expire. CSRF cookies / tokens are valid as long as the browser session is kept alive, i.e. the browser window is kept open.
Comments.UserDisplayName: MoritzLost
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-04-22T15:16:28.260Z
Comments.Text: Yes, I'm talking only about logged-in users. In this specific case, I'm using the Sprig plugin: https://github.com/putyourlightson/craft-sprig/issues/365
Comments.UserDisplayName: Romain P.
Tags: <javascript><session>
Title: How to inform the front-end user that their session is about to expire?
ThreadText: # How to inform the front-end user that their session is about to expire?
  
  (Asked by: username_0 on 2024-04-22)
  
  I have a Craft CMS 4 with forms for logged-in users.
  
  Some users may keep certain pages open in their browsers.
  Sometimes, users submit the form while their session has expired (after one hour, in this case).
  
  This generates a validation error:
  
  ```
  [web.ERROR] [yii\web\HttpException:400] Unable to verify your data submission.
  
  ```
  
  How can we, probably via JavaScript on the client side:
  
  * Display a message to the user when their session is about to expire
  * Redirect the page to the login URL just before the session expires
  
  **Tags:** javascript, session
  
  > **Comments:**
  > **username_1**: You're talking only about logged-in users, right? Because if I'm not mistaken, only login sessions expire. CSRF cookies / tokens are valid as long as the browser session is kept alive, i.e. the browser window is kept open.  
  > **username_0**: Yes, I'm talking only about logged-in users. In this specific case, I'm using the Sprig plugin: https://github.com/putyourlightson/craft-sprig/issues/365  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2024-04-22. Score: 5 | Accepted answer
  
  You can check the remaining time in the session with JavaScript using Craft's [`users/session-info` controller action](https://craftcms.com/docs/4.x/dev/controller-actions.html#get-users-session-info). This endpoint returns an object like this as a JSON response:
  
  ```json
  {
      "isGuest": false,
      "timeout": 10800,
      "csrfTokenName": "CRAFT_CSRF_TOKEN",
      "csrfTokenValue": "5bJjI1cYVEJ_QhYugiIOOY2CFVhy3RSFwJE96rRNZa6WhSMlL0j7O2e9pgexUgQBhRJ-cC8rjUBTZ8ASSarw3pBy__-buyTujPuxqIxG7OFK3hC0lRjFnw_2WOr3bf-QS7bSQjJONtlgUS7_SZBCSGCFUtZG5h99v2LqfganVeyJqrouOv765YUT-MTpvmlped6_hMM0ZAFULjAGKFN-0khCD-bTIxMfv1zx7fBSk_0DFPbH31RSHBGPThuFkmTTZWEy5yMYQx4TuiFqBaV0eZPE5qAWmsui2RzY7cnSyrol2oBzvCOE8y7yq26UPN-TCJ7xco_kegotVesBNF-oDsYOMhL8OJMWtnUxiQm7SE3KN6T9h9tBQ7e0lN1CorOejTAdDKKO",
      "id": 1,
      "uid": "aaaaaaaa-1234-49a3-808f-449f78537bb5",
      "username": "user@example.com",
      "email": "user@example.com"
  }
  
  ```
  
  What you're interested in is the `timeout`, which is the number of seconds left until the current session expires. Note that this will always return `0` for guests, so this only works for logged-in users.
  
  You can get the session info like this:
  
  ```js
  const session = await fetch('/actions/users/session-info', {
      credentials: 'include',
      headers: { 'Accept': 'application/json' },
  }).then(res => res.json());
  
  ```
  
  By default, the controller action will *extend* the current session, so the `timeout` will pretty much always be the same as your `userSessionDuration` setting. You could just call this method periodically and call it a day.
  
  If you want to be smart about it, you can also tell the controller action not to extend the current session by appending a URL parameter to the request: `/actions/users/session-info?dontExtendSession=1`
  
  This will tell you the timeout of the current session without extending it. You can use this information to either set a timeout for when to warn the user, or just to extend the sessions (using the same controller action) automatically before the timeout is reached.
  
  The Control Panel does something similar, see [`AuthManager.js`](https://github.com/craftcms/cms/blob/5.x/src/web/assets/cp/src/js/AuthManager.js) for inspiration.
  
  
  ---
  
  