简体   繁体   中英

Classic ASP / End of session redirect

I want to automatically redirect to the login page when the users session has expired.

I have been using the following code in an include file that sits at the top of every page in my application:

Session.Timeout = 60
Response.AddHeader "Refresh", CStr(CInt(Session.Timeout + 1) * 60)
Response.AddHeader "cache-control", "private"
Response.AddHeader "Pragma","No-Cache"
Response.Buffer = True
Response.Expires = 0
Response.ExpiresAbsolute = 0

If Session("accountID") = "" Then
    Response.Redirect("http://www.mydomain.com/")
End If

This works but there is very slight bug. Every now and then the page will refresh even though the session is still alive and it seems that it refreshes before the 60 minutes is up!

Can anybody see what the problem is or can you suggest a different method?

Seeing as though you have to do this client side I'd favour JavaScript/jQuery and AJAX over that method. Here's an example of how to do it.

Essentially you just set-up an AJAX call to poll a script which returns (in JSON format) whether the user is logged in or not; if they're not then you can transfer them to another page.

The benefits to this method are that you can poll whenever you want; eg every 10 seconds to see whether the user is still logged in rather than having to wait a full hour. It also means that you don't need to state the session time-out figure in your code and so you can leave that to be determined in IIS. Also if the user logged off elsewhere in your system, or your application pool recycled and their session was reset this would detect it fairly quickly.

I notice from your profile that you're a Paparazzi photographer. I'd consider this the DSLR method and the response header method the cheap phone camera method :o.

To build your session checker page create a file called session.asp (in the same folder as your other files to make life simpler). In it put:

<%
Response.ContentType = "application/json"
If Session("LoggedOn") Then
   Response.Write "{""loggedOn"": true}"
Else
   Response.Write "{""loggedOn"": false}"
End If
%>

If the user is logged in it returns {"loggedOn": true}, if they're not {"loggedOn": false}. This is what we'll use on your other page to poll if they're logged in by calling this page periodically and reading the response.

Now onto your pages which originally had your Response.AddHeader code in. Remove all of your code as this replaces it.

First make sure you have a reference to jQuery on your pages:

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>

And then put under this line the following:

<script type="text/javascript">
    $(document).ready(function() {

        var checkLoggedOn = function() {
            $.getJSON('session.asp', function(data) {
                if (!data.loggedOn)
                    window.location.replace("http://stackoverflow.com");
            });
        };

        // Call checkLoggedOn every x milliseconds
        setInterval(checkLoggedOn, 30000);
    });
</script>

All being well, it should work. I set the above to poll every 30 seconds (30000) but you could increase/decrease this to whatever you wanted.

Note I borrowed large parts of the code above from https://stackoverflow.com/a/4928564/171703 and https://stackoverflow.com/a/2709160/171703 .


Update:

From the comments below, if you want the user's session to expire after the timeout figure (whether they are keeping their session alive or not) then you could do this.

When the user is logged in, set a new session variable for LoginExpiration:

Session("LoginExpiration") = DateAdd("n", Session.TimeOut, Now())

This takes the current time and adds to it the session timeout figure - giving you the time when their session should be destroyed.

If you now modify your session.asp to the following it takes the LoginExpiration figure and returns that the user is not logged in the event of:

  1. The users session has timed out (IIS application pool reset, or they clicked logoff etc)
  2. The current date/time is greater than the set LoginExpiration time

Which is:

<%
Response.ContentType = "application/json"

LoggedOn = "false"
LoginExpiration = Session("LoginExpiration")
DateNow = Now()

If IsDate(LoginExpiration) Then
    If DateNow < LoginExpiration Then
        LoggedOn = "true"
    End If
End If

Response.Write "{"
    Response.Write """loggedOn"": " & LoggedOn & ", "
    Response.Write """loginExpiration"": """ & LoginExpiration & """"
Response.Write "}"
%>

I've put the loginExpiration figure into the JSON response so you could work with it client side if you wanted too.

The ASP Global.asa file may be what you're looking for. It allows you to run code at certain events, such as Session start and end. See https://www.w3schools.com/asp/asp_globalasa.asp for more info, but I believe the following will work:

Global.asa

<script language="vbscript" runat="server">
    sub Session_OnEnd
        Response.Redirect("http://www.example.com/")
    end sub
</script>
'If the session variable is False or does not exist (IsNull)
'then redirect the user to the unauthorised user page
If Session("accountID") = False or IsNull(Session("accountID")) = True then
 'Redirect to unathorised user page
 Response.Redirect "pagename.asp"
End If 

Place this in an include file that you include in all pages you need protected.

<%@LANGUAGE="VBSCRIPT"%>
<!--#include file="checkmem.asp"-->
<!--#include file="includes/dtdsql.asp" -->
<!--#include file="includes/functions.asp" -->

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM