Geeks With Blogs
Frez Phil Fresle's Developer Blog
| Home |

This is the code most of us would normally use when logging out a user:

FormsAuthentication.SignOut();
FormsAuthentication.RedirectToLoginPage();


A frequent problem is that after a user logs out of their application using this code or similar, if they then use the back button they are presented with pages from the application without having to login. The reason that this problem occurs is because the client browser is caching the output from the pages and when the Back button is pressed the page content shown last is displayed directly from the cache without executing the code behind that might otherwise detect the user is unauthenticated and deny access if instead the page had been requested from the server again.

One solution might be to send appropriate headers with every page in the application to ask the browser not to cache the pages. This will work but it will mean that we will have to ensure that the headers are sent with each and every page either by either posting the same code on every page, using master pages or by having a common base class for every page, it will also mean that when the user uses the Back button in our application they will be hitting the server for the page every time rather than retrieving it from their browser cache which may not be desirable for performance reasons.

My solution is to use a half-way house that prevents the back button returning to an authenticated page after logout, when authenticated allows the back button to work as usual in retrieving the page from the browser cache, but has the downside that the user can still choose to access a page from their browser history after logging off as long as it is still in the browser's cache.

The first step is to create a logout.aspx page and have our logout button simply redirect the user to this page. The logout page is going to request that the browser does not cache it and then log the user out of the application.

In the Page_Load event for the logout.aspx page, enter the following code:

Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1)); 
Response.Cache.SetCacheability(HttpCacheability.NoCache); 
Response.Cache.SetNoStore();
 

This code will request that the browser does not cache the page, but this will only occur if the response finishes and the page is displayed, i.e. we cannot simply do a SignOut and RedirrectToLoginPage within the Page_Load event.

The next step is to add an Ajax ScriptManager and Timer to the logout.aspx page as we are going to user the timer's tick event after the page has been displayed for a second to logout and redirect the user. So paste this code into the page (ensuring that you have also included ajax in your project):

<asp:ScriptManager ID="ScriptManager1" runat="server"> 
</asp:ScriptManager> 
<asp:Timer ID="Timer1" runat="server" Interval="1000" ontick="Timer1_Tick"> 
</asp:Timer>


Then you can code the Timer1_Tick event to logout the user and redirect them to the login page. Unfortunately, we cannot use RedirrectToLoginPage to redirect them as this would have a return url of our logout page, so we will put together our own url so that the user is redirected to index.aspx (you could change the code to redirect to any page of your choosing when the user logs in). Paste this code (or similar) into the Timer1_Tick event of the logout.aspx page:

string redirectUrl = FormsAuthentication.LoginUrl + "?ReturnUrl=index.aspx"; 
FormsAuthentication.SignOut(); 
Response.Redirect(redirectUrl); 


So, when the user clicks the logout button in our application, the logout.aspx page will be displayed, perhaps with a message saying "Logging out…", for a short period depending on what we have decided is a suitable interval (I use 1 second), and then the user is redirected to the login page. The user will now find that the Back button does not work and when they login they are redirected to the index page.

This solution still has an issue raised by some posters below, and that is if the user clicks the back button multiple times they will be able to get to the old pages, also, the Opera browser does not appear to respect the instructions we pass not to cache the logout page. A workaround to this is to add the following javascript code to the <head> section of the logout.aspx page:
 

<script type="text/javascript">
 window.history.forward(1);
</script>

This javascript code will forward the user back if the user gets to the logout page by pressing the back button.

Note that, as discussed above, these tips ara a half-way house solution. If you need to ensure the user has no way to get back to the pages after they logout you must ask the browser not to cache any of the pages by including code similar to the following on every page:

Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1)); 
Response.Cache.SetCacheability(HttpCacheability.NoCache); 
Response.Cache.SetNoStore();
 

 

Posted on Tuesday, May 18, 2010 1:20 PM | Back to top

Copyright © Frez | Powered by: GeeksWithBlogs.net | Join free