I have created a heartbeat mechanism to keep the user's session alive. It will run every 60 seconds. Question is, why not set this to like 15 minutes? Also, why use a heartbeat at all; can't I just set my session expiration time in IIS?
I just want to make it so if a user leaves the page for a half hour or so and goes and gets lunch, that they can come back and their session will still be there when they click submit, so they won't lose any data they might have entered before they left.
$(function () {
// every 60 seconds...
setInterval(KeepSessionAlive, 60000);
});
function KeepSessionAlive() {
$.post("/FACTS/_code/Heartbeat.ashx", null, function () {
//console.log('Session is alive and kicking');
});
}
This can be configured if you are using Session within the .NET framework.
A snippet from http://msdn.microsoft.com/en-us/library/h6bb9cz9%28v=vs.100%29.aspx describes how to set a timeout parameter in your web.config if you are using SessionState
<configuration>
<system.web>
<sessionState
mode="[Off|InProc|StateServer|SQLServer|Custom]"
timeout="number of minutes">
<providers>...</providers>
</sessionState>
</system.web>
</configuration
Related
I have a web application that utilizes JQuery as my front end code and ASP.NET as my backend web service.
I set the web.config setting <sessionState timeout="1">. When the user logs in, the web service creates a session variable with the user name.
System.Web.HttpContext.Current.Session["UserID"] = user_id;
In my web service, I have a function that checks if the variable still exists.
[WebMethod(EnableSession = true)]
[ScriptMethod(UseHttpGet = true)]
public string GetSessionUserID()
{
string user_id = "";
if (System.Web.HttpContext.Current.Session["UserID"] != null)
{
user_id = System.Web.HttpContext.Current.Session["UserID"].ToString();
}
return user_id;
}
I have a JS function that calls the web service that calls GetSessionUserID().
$(document).ready(function () {
getSessionID();
setInterval(getSessionID, 3000);
function getSessionID() {
console.log("getSessionID");
$.ajax({
url: "photoapp.asmx/GetSessionUserID",
//data: ,
success: OnGetSessionIDSuccess,
error: OnGetSessionIDError
});
}
function OnGetSessionIDSuccess(data, status) {
console.log("Success OnGetSessionIDSuccess");
console.log(data);
var strUser = $(data).find("string").text();
console.log(strUser);
if (strUser == "") {
window.location = "login.html";
}
}
}
In the document ready function, I also call setInterval() which will check the session every 3 seconds.
When testing, getSessionID gets called every 3 seconds, but after a minute, the getSessionID user variable can be found. I want the redirect the user back to login.html after the minute is done. Why is the session variable still alive after a minute? What am I not understanding about ASP.Net session state? How can this be fixed?
Be aware that if you adopt SQL server to save the session state, then the session timeout events never get called, and you thus can't know or tell if the user actually has logged out.
The only possible solution then is to ensure that all web pages have some kind of heartbeat or routine that calls the server every minute or so, and when that stops, then you know the user is gone or closed the web page.
In your case? If you touch the server every 3 seconds, then the session timeout will be re-set and start over with 1 minute. You also don't mention if you using in-memory, or using sql server for session state.
If you want to jump back to the logon page? Then your 3 second js code has to get/grab the time of the last heartbeat you call every 3 seconds. So, that routine has to set a start time, and then every 3 seconds check the elapsed time. Keep in mind that if you use sql sessions, then not even the logon event will fire, nor will even the authenticated user event fire.
So, the first time you start running that routine, you need to set a session value with the start time.
However, to my knowledge, every web service call will re-set the session time out to start over to 0. session timeout gets re-set when no activity occurs. So, if the user is doing something (or your ajax calls are), then session timeout will never occur.
You have to set a start time. And then get the elapsed time from that. You session will never timeout as long as you have the web page hitting and talking to the server.
I am using this to login:
var f = from b in db.AdminToybias
where b.UserName == a.UserName
&& b.Password == a.Password
select b;
if (f.Count() >= 1)
{
Session["uname"] = f.FirstOrDefault().UserName;
Session["pass"] = f.FirstOrDefault().Password;
Session["role"] = f.FirstOrDefault().Role;
I tried both:
<sessionState timeout="1440" mode = "InProc"></sessionState>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="288000" />
</authentication>
But the application automatically logout user after few mins (don't know exact time). I want to get session unlimited time untill he manually logout.
I tried so many hours but failed. What can i do to achieve this?
I am using Godaddy Hosting.
They are different things. The Forms Authentication Timeout value sets the amount of time in minutes that the authentication cookie is set to be valid, meaning, that after value number of minutes, the cookie will expire and the user will no longer be authenticated - they will be redirected to the login page automatically-. The slidingExpiration=true value is basically saying that after every request made, the timer is reset and as long as the user makes a request within the timeout value, they will continue to be authenticated. If you set slidingExpiration=false the authentication cookie will expire after value number of minutes regardless of whether the user makes a request within the timeout value or not.
The SessionState timeout value sets the amount of time a Session State provider is required to hold data in memory (or whatever backing store is being used, SQL Server, OutOfProc, etc) for a particular session. For example, if you put an object in Session using the value in your example, this data will be removed after 30 minutes. The user may still be authenticated but the data in the Session may no longer be present. The Session Timeout value is always reset after every request.
I have a simple question but not able to find solution to it. I have set session timeout of the application in the web.config as :
<sessionState timeout="30" mode="InProc"/>
and its working fine but now I got the requirement that if the user is idle that is, he is not performing any action on the page for one minute his session should get expired. I tried to do it using form authentication as :
<authentication mode="Forms">
<forms loginUrl="~/Login.aspx" timeout="1" slidingExpiration ="false" defaultUrl="login.aspx"/>
</authentication>
But its now working. Any help would be appreciated.
If I have understood the question correctly (see comments by OP) then the problem is that OP wants both slidingExpiration and absoluteExpiration to be active, but with separate timeouts.
This would enable the system require a user to log back in after a certain time of idling, and to require a user to log back in after a different time even if the user was not idling.
Unfortunately this is not supported out of the box using forms authentication. You have to choose either sliding or absolute expiration. Or you have to build a workaround yourself.
You can use a very simple work around by:
Setting the timeout of the session longer than the corresponding forms authentication timeout, and also longer than the desired absolute timeout:
<sessionState timeout="35" mode="InProc"/>
Set forms authentication to use slidingExpiration = true
Create a user logged in timestamp in the session whenever a user logs in:
Session["userLoggedInAt"] = DateTime.UtcNow;
Add an Application_PostAcquireRequestState method to Global.asax:
void Application_PostAcquireRequestState(object sender, EventArgs e)
{
HttpContext context = ((HttpApplication)sender).Context;
if (context.Session != null && context.User.Identity.IsAuthenticated)
{
bool forceLogout = false;
if (context.Session["userLoggedInAt"] == null)
forceLogout = true;
else if (!(context.Session["userLoggedInAt"] is DateTime))
forceLogout = true;
else if (DateTime.UtcNow > ((DateTime)context.Session["userLoggedInAt"]).AddMinutes(30))
forceLogout = true;
if (forceLogout)
{
FormsAuthentication.SignOut();
FormsAuthentication.RedirectToLoginPage();
}
}
}
Disclaimer: Code above was hacked together quickly, may not be fool proof...
Notes:
Setting sliding expiration to timeout after 1 minute seems excessively paranoid. Even a fast user will not be able to finish any significant work in the application during that time. Even my web bank has a longer idle timeout that that. I would recommend a minimum of 5-10 minutes.
Sliding expiration in forms authentication has an interesting feature: The sliding happens by updating the authentication cookie, moving the expiration date forward when the user is active. But this only happens when at least half the expiration time has passed. If you want to guarantee that a user can be idle for 10 minutes without getting logged out, you must therefore set the timeout to be 20 minutes.
I am a new ASP.NET Webforms developer and I am struggling right now with how to have and manage session timeout in my simple test application. Generally speaking, the test application is listing a number of items. The user can add whatever he wants to a shopping cart and when he clicks on Checkout, he will be asked to enter his information. There is no login or authentication. However, I am using session variables to pass the user information between different pages.
I need to have a timeout here in such a case that the user leaves the page for a long time. In this case, he should get a message and gets redirected to the home page or any other page.
How to do that?
I tried to do that by adding the following to the web.config file:
<sessionState
mode="InProc"
stateConnectionString="tcpip=127.0.0.1:42424"
stateNetworkTimeout="60"
sqlConnectionString="data source=127.0.0.1;Integrated Security=SSPI"
cookieless="false"
timeout="60"
/>
I was trying to retrieve thousands of records from a web service according to the input parameters and naturally it was trowing timeout exceptions. I decided to put the following code in action to display a client-side message, so the user would change the input parameters to make the results more specific.
You can find this example in here.
Executes any code block:
public static bool ExecuteWithTimeLimit(TimeSpan timeSpan, Action codeBlock)
{
try
{
Task task = Task.Factory.StartNew(() => codeBlock());
task.Wait(timeSpan);
return task.IsCompleted;
}
catch (AggregateException ae)
{
throw ae.InnerExceptions[0];
}
}
For a specific amount of time:
bool Completed = ExecuteWithTimeLimit(TimeSpan.FromHours(1), () =>
{
/*your code block*/
});
After stopping the execution, you can redirect to the desired page.
First off I'd like to point you to this page here as it seems that:
You are using InProc mode, though providing state server information and timeout which does not make much sense.
There are different modes in this so most probably you only need
mode, timeout and cookieless items for InProc (which is the best choice for test applications)
Have you made sure that this is under system.web in web.config?
<configuration>
<system.web>
<sessionState mode="InProc"
cookieless="false"
timeout="20"/>
</sessionState>
</system.web>
</configuration>
As an extra, your timeout is 60 minutes. Have you waited long enough? If the session is not set anymore you need to handle the redirect yourself.
Here is another SO page that might help you
By the way, if you are to use the in proc mode you can handle session expiry in global.asx
void Session_End(object sender, EventArgs e)
{
// Code that runs when a session ends.
// Note: The Session_End event is raised only when the sessionstate mode
// is set to InProc in the Web.config file. If session mode is set to StateServer
// or SQLServer, the event is not raised.
Response.Redirect("Add url here");
}
I am doing a group project with 4 other people. We are designing a job kiosk in ASP.NET in MVC4 with embedded c#.
I am working on having the system log the user out if they are idle for 10 minutes. I need some help on how to start coding a way for the system to log the user out.
If you don't use "Windows Authentication", this at least depends on the session timeout you can control via web.config:
<configuration>
<system.web>
<sessionState timeout="10" />
</system.web>
</configuration>
As most techniques somehow rely on sessions, this will work in most scenarios.
the answer you are looking for is the one AliK suggested. You want to set an automatic timeout in the web.config so that it will automatically logout the user and redirect them to the login page after a certain amount of idle time.
<authentication mode="Forms">
<forms loginUrl="Login.aspx" protection="All" timeout="1" slidingExpiration="true">
</forms>
</authentication>
If I remember right, the timeout value is in minutes, not seconds or milliseconds. Also the sliding Expiration means that the timeout will reset each time you perform an action on the website. So if you have a timeout of 5 minutes and you sit idle for 4 before clicking a button on the site then after the button click you get a new 5 minute timeout.
Here is how I do it if you are using FormsAuthentication:
Controller Action:
public ActionResult CheckLogin()
{
if (Request.Cookies["CookieName"] == null) return Json(0, JsonRequestBehavior.AllowGet);
var cookie = Request.Cookies["CookieName"].Value;
var ticket = FormsAuthentication.Decrypt(cookie);
var secondsRemaining = Math.Round((ticket.Expiration - DateTime.Now).TotalSeconds, 0);
return Json(secondsRemaining, JsonRequestBehavior.AllowGet);
}
Jquery on each page or on layout page:
<script>
$(function () {
setTimeout(doStuff, 1000);
});
function doStuff() {
$.ajax("/CheckLogin").done(function (data) {
if (data <= 60) {
startLogout(data);
} else {
setTimeout(doStuff, 1000);
}
});
}
function startLogout(seconds) {
var countdown = setInterval(function () {
//Show something here
if (count == 0) {
clearInterval(countdown);
//Do something here
}
seconds--;
}, 1000);
}
</script>
If you need to have them automatically logged out, start with Linus Caldwell's suggestion of setting the web.config session timeout. His example shows 30 minutes, so you would just change it to 10. The user won't know that they're logged out, though, until they actually try to request some server resource. To have that happen automatically, you can go a couple of ways. Both of these ways involve automatically refreshing the page after the timeout period has expired. One way is to use a javascript timer. The other is to add a refresh header to each page.
<script type="text/javascript">
var seconds = 60 * 11;// set timer for 11 minutes (1 minutes after session expires)
countdown();
function countdown(){
seconds--;
if (seconds <= 0){
window.location.reload(); // force a refresh.
}else{
setTimeout('countdown()', 1000);
}
}
</script>
The other way would be in your global.asax:
protected void Application_BeginRequest()
{
Response.Headers.Add("Refresh", Convert.ToString(Session.Timeout * 11));
}
If by Idle you mean absence of mouse and keyboard events from user, and i understand your requirement correctly, you should check the jquery-idleTimeout plugin.
Another good one is jQuery idleTimer Plugin
hope this helps.