"Remember Me" with asp.net web pages
Asked Answered
T

2

9

I realize that this question may have been asked before, but I can't find anything that matches my situation exactly.

I created a website using the WebMail helper in ASP.Net web pages (not web forms) and WebMatrix. Users are required to login to the website, and there is a "Remember me" box that (in theory) will keep the user logged in until he/she chooses to log out. The website does keep users logged in if they close the browser and reopen it within 20-30 minutes. However, after 20-30 minutes of not accessing the website, the user is logged out. (As an aside, this problem seems to exist even with the WebMatrix template "Starter Site".)

I've tried multiple solutions, many of which were posted on Stack Overflow, but nothing seems to work.

Titleholder answered 6/8, 2013 at 14:16 Comment(3)
What 'multiple solutions' have you tried? Would help to know so we don't repeat them.Laflamme
Unfortunately, I didn't save the attempts that didn't work, so I can't tell you exactly what I tried. Most involved trying to create a cookie that could be accessed by my website, but I'm not sure if I created the cookie correctly or if my attempts to access it were right.Titleholder
I would expect that somewhere in that code template, there is a condition, which checks current session inactivity duration. Look through the authentication code and see if there is a time check or something like that.Retarder
L
14

EDIT 2

The cookie used by Forms Authentication is called ".ASPXAUTH" and by default set to expire after 30 minutes.

Go to your web.config and find the authentication element. You can set the cookie expiration time (in minutes) there, like such:

<system.web>
    <authentication mode="Forms">
        <forms loginUrl="~/Account/Login" 
               name="myCookie"                  <!-- optional, if you want to rename it -->
               timeout="2880" />                <!-- expires in 48 hours -->
    </authentication>
</system.web>

OR

If the config fails you, try this article: Link

You'll need to clear any existing auth tickets and create your custom one. It boils down to this piece of code you need to execute if the user selected the remember me option:

    if (rememberMe)
    {
        // Clear any other tickets that are already in the response
        Response.Cookies.Clear(); 

        // Set the new expiry date - to thirty days from now
        DateTime expiryDate = DateTime.Now.AddDays(30);

        // Create a new forms auth ticket
        FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(2, loginModel.UserName,  DateTime.Now, expiryDate, true, String.Empty);

        // Encrypt the ticket
        string encryptedTicket = FormsAuthentication.Encrypt(ticket);

        // Create a new authentication cookie - and set its expiration date
        HttpCookie authenticationCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
        authenticationCookie.Expires = ticket.Expiration;

        // Add the cookie to the response.
        Response.Cookies.Add(authenticationCookie);
    }
Laflamme answered 6/8, 2013 at 14:39 Comment(13)
That's right but, some hosting, do not allow the setting timout and even by setting the configuration it is overwritten.Shurwood
On second thought, setting session timeout wouldn't be a good solution. His cookie simply times out, so the correct solution would be to set its expiration time when the user logs in. Updated the answer.Laflamme
Yes. It's all sample code, but I suppose yours looks somewhat similar. The important bit is where the cookie expiration time is set after authentication succeeds.Laflamme
I spoke too soon -- I got logged out after an hour. :-(Titleholder
@Trickery Curious: I see where you are setting the expiration date for the cookie [0], but I fail to see how this cookie (which I fail to even see a name for) is checked by ASP.NET. Perhaps the Session time out (which is handled in more places than the web.config file) should be looked at? I mean, as far as I know, no data is being stored to remember this added expiration time (at least not in the appropriate place). Am I mistaken?Anchorage
You are correct, I should have used a name for it. I just grabbed this code quickly off Google. But just any name won't do. You need to use whatever is assigned to WebSecurity. Long session timeout is not the correct approach. There is no reason why the server should hold a session in memory for a month, not to mention it will probably be restarted/crash at some point. I updated my answer with a more thorough and complete solution.Laflamme
@Trickery I learned a bit from your answer, myself. Thanks for that, but was wondering if you were able to detail what the arguments do for some of the methods used (especially FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(2, loginModel.UserName, DateTime.Now, expiryDate, true, String.Empty);, but also, HttpCookie authenticationCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);). Some of the arguments are self-explanatory and I'm sure the methods have overloads, but I would love to know what the arguments I don't understand do.Anchorage
Sure. This article should explain everything: LinkLaflamme
The browser didn't like "loginModel.UserName". I changed it to my variable for the user's name ("Email"), and it let me log on. Now, it's a waiting game to see if the cookie will last more than 30 minutes. Stay tuned.Titleholder
Well, yes, it's just sample code. Did the config solution not work?Laflamme
Sorry, I'm an extreme newbie. I appreciate your help. Which config solution? If you mean the code you posted yesterday, the answer is no. If you mean the code shown above, I'm testing it right now.Titleholder
The code shown above is 2 different solutions. You can set things in your web.config, as shown in the first part, or you can use the code I posted. You probably don't need both.Laflamme
OK, it appears to be working! I will mark this as a solution once it passes the "one hour test". Thank you so much for your help!Titleholder
R
1

You can manually create a cookie(never expiring) containing a GUID which is mapped to your user. When user makes a GET to your user login page, you can read that cookie and check the guid and authenticate the user. check the links

http://msdn.microsoft.com/en-us/library/ms178194(v=vs.100).aspx

http://msdn.microsoft.com/en-us/library/78c837bd(v=vs.100).aspx

http://www.codeproject.com/Articles/31914/Beginner-s-Guide-To-ASP-NET-Cookies

Rodmun answered 7/8, 2013 at 8:28 Comment(1)
So the way I understand it is that I still need to keep some piece of information on the server (the GUID) for every log-in with the 'remind me' option... and eventually these need to expire and get purged somehow. Right?Microstructure

© 2022 - 2024 — McMap. All rights reserved.