【问题标题】:Sessions ASP.NET Timeout会话 ASP.NET 超时
【发布时间】:2015-06-02 14:31:57
【问题描述】:

我在 asp.net 中的会话有问题。我在网上搜索了一段时间,但找不到它不起作用的原因。会话在几分钟后消失。这是一个不是我自己创建的项目,我不是aspx中的英雄。但我正在努力解决这个问题。

Web.config

 <system.web>
     <authentication mode="Forms">
        <forms loginUrl="~/Default.aspx" timeout="120" slidingExpiration="true" />
     </authentication>

    <customErrors mode="RemoteOnly"/>
    <httpRuntime requestValidationMode="2.0"/>
    <pages validateRequest="false" />

    <sessionState mode="InProc" cookieless="false" timeout="120"  />

  </system.web>

在您必须登录的页面上检查是否已登录 if (!functions.isLoggedIn(Session)) { Response.Redirect("Default.aspx"); } 功能

public static bool isLoggedIn(HttpSessionState session)
        {
            return session["user"] != null;
        }

没有登录?显示登录表单,填写表单发送到服务器查看

protected void Page_Load(object sender, EventArgs e)
    { 
       if (Request["do"] != null)
        {
            switch (Request["do"])
            {
                case "logout":
                    Session.Abandon();
                    break;
            }
        }
     if (Request.ServerVariables["REQUEST_METHOD"].ToLower() == "post")
                {
                    //get username en password
                    string username = Request["username"];
                    string password = Request["password"];
                    if (String.IsNullOrWhiteSpace(username) || String.IsNullOrWhiteSpace(password))
                    {
                        LoginMessage.Text = "Please fill in all the fields...";
                    }
                    else
                    {
                        password = FormsAuthentication.HashPasswordForStoringInConfigFile(
                                password,
                                "SHA1");
                            UserService gs = new UserService();
                            user g = gs.getUserByLogin(username, password);
                        if (g == null)
                        {
                            //wrong login
                            LoginMessage.Text = "Invalid username/password.";
                        }
                        else
                        {
                            //good login
                            Session["user"] = g;
                            System.Diagnostics.Debug.WriteLine("timeout:" + Session.Timeout);
                            Response.Redirect("Home.aspx");
                        }
                   }
    }
}

用户服务中的GetUserByLogin函数

public user getUserByLogin(string username, string password)
        {
            user g;
            var db = new projectName.Db.Models.projectnetContext();

            IQueryable<user> query = from gb in db.users
                where gb.username.Equals(username)
                      && gb.Passwoord.Equals(password.ToLower())
                      && gb.Status == 1
                select gb;

            if (!query.Any())
                g = null;
            else
                g = query.First();

            return g;
        }

登录后,创建会话

Session["user"] = g;

我的问题是我设置了超时。但这似乎不起作用。如果我检查服务器上的超时,它设置为 120。但 2 分钟后,我被重定向到登录表单。我可以解决这个问题吗?如果我在 localhost 上调试,它似乎可以工作,但不能在线。

登录有效。会话已设置(否则我无法进入下一页)。如果我转到另一个页面(快于 +-5 分钟),那么我仍然处于登录状态。所以问题是再生问题。

或者如果不可能的话,Cookies?通常我在 PHP 中使用 cookie,.. 但是有没有办法在 ASP.NET 中以安全的方式做到这一点?

【问题讨论】:

  • 我很久以前写过这篇文章,希望对您有所帮助...aspalliance.com/…
  • 根据您的配置,会话值存储在 Proc 中,因此也取决于 w3wp.exe 进程。如果 applicationPool 重新启动的会话丢失。
  • 我不确定我是否理解这一点。将项目上传到网络服务器后,我再次登录。但问题依然存在。自从上传到服务器后,我没有更改其他内容。

标签: asp.net session cookies session-timeout


【解决方案1】:

嗯,我建议您在 asp .net 中使用配置文件而不是会话。

【讨论】:

    【解决方案2】:

    您的方案有两个方面。您拥有身份验证和会话。这是两个不同的东西。

    您在 web.config 中管理的会话存储了一个超时 120 分钟(2 小时)的值

    但身份验证在 web.config 中也有一个配置部分。 https://msdn.microsoft.com/en-us/library/532aee0e%28v=vs.85%29.aspx

    那么你首先想做什么呢?

    【讨论】:

    • 我已经在 web.config 中使用了身份验证。现在我将它添加到全球帖子中。这个超时时间也设置为 120。
    • 好的,但是你如何认证用户呢?你没有发布任何代码,你是怎么做的……你能发布这段代码吗?
    • 我添加了一些额外的代码。填写登录表单后会发生什么,... 还是缺少什​​么?
    • 我将发布一个使用表单身份验证的 POC 项目示例来说明我试图向您解释的内容 ;-)
    【解决方案3】:

    请查找此 MVC 控制器操作方法示例。

        // POST: /Secure/Login
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public ActionResult Login(LoginFormModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (Membership.ValidateUser(model.Login, model.Password))
                {
                    using (var db = new DatabaseEntities())
                    {
                        var user = db.Users.Single(u => u.Login == model.Login);
    
                        Membership.UpdateUser(new MembershipUser("UserMembershipProvider", user.Login, null, null, null, null, true, false, DateTime.MinValue, DateTime.Now, DateTime.MinValue, DateTime.MinValue, DateTime.MinValue));
    
                        #region Create Authentication Cookie
    
                        Response.Cookies.Add(MyAppFormAuthenticationCookie.Create(user, model.RememberMe));
    
                        #endregion
    
                        if (!string.IsNullOrWhiteSpace(returnUrl))
                        {
                            return Redirect(HttpUtility.UrlDecode(returnUrl));
                        }
    
                        if (model.UserFormType == UserType.Candidate)
                        {
                            return RedirectToAction("Index", "Dashboard", new { area = "Candidate" });
                        }
    
                        if (model.UserFormType == UserType.Recruiter)
                        {
                            return RedirectToAction("Index", "Dashboard", new { area = "Recruiter" });
                        }
    
                        if (model.UserFormType == UserType.SuperAdmin || model.UserFormType == UserType.Admin)
                        {
                            return RedirectToAction("Index", "Dashboard", new { area = "Admin" });
                        }
                    }
                }
    
                ModelState.AddModelError("", "Incorrect username and/or password");
                return View("Index", model);
            }
    
            return RedirectToAction("Index", "Home");
        }
    

    在此示例中,您有:

    • 更新用户配置文件以设置最后连接日期和其他日期(如果需要)...
    • 为此示例以自定义方式创建身份验证 cookie
    • 根据用户类型重定向到主页

    那么,您是否有类似的方法在您的应用程序中对用户进行身份验证?

    编辑1:

    通常您必须完成类似这样的身份验证过程:

            var authTicket = new FormsAuthenticationTicket("MyAuthTicket", rememberMe, timeout: 120);
            var encryptAuthTicket = FormsAuthentication.Encrypt(authTicket);
            Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encryptAuthTicket) { Expires = authTicket.Expiration });
    

    【讨论】:

    • 我对用户进行身份验证的部分位于第三个代码块(全球帖子)中。我什么都没有了?
    • 但身份验证不能只是针对数据库对象检查登录名/密码。您必须保留身份验证令牌,这必须感谢 FormsAuthentication。请参阅 EDIT1
    • 所以我不使用身份验证,还是我错了?我唯一要做的就是将 g 存储在会话用户中,并且我还有 FormsAuthentication.HashPasswordForStoringInConfigFile
    • 是的,您对用户进行了身份验证,但您没有给他允许他证明他的身份验证的票证。它可以工作,但并不安全可靠。是的,我已经看到您使用了 FormsAuthentication.HashPasswordForStoringInConfigFile 但您可以在 MSDN 文档 (msdn.microsoft.com/fr-fr/library/…) 中阅读,它不是对用户进行身份验证,它只是加密密码,因为您可能已经注册了用户。
    • 好的,我会阅读文档并在接下来的几天内尝试一下。
    【解决方案4】:

    只是一个建议...您是否有任何重定向(Response.Redierct)来区分。网站或试图访问您无权访问的资源?在这些情况下,会话将过期。

    【讨论】:

    • 是的,我有重定向(在检查用户是否登录后(= 会话集))。但是是到同一个站点的一个页面,登录表单页面(=default.aspx)
    • 如果您使用的是 Response.Redirect 是否可以将其更改为 Server.Transfer 并尝试一下。
    • 嗯,就像您在全球帖子中看到的那样,只有在检查会话之后。不是以前。 --> functions.isLoggedIn(Session).
    • 即使response.redirect转到另一个网站,会话也不会丢失,因为会话已附加到服务器,因此用户关闭浏览器后不会丢失;-)
    猜你喜欢
    • 2010-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-03
    • 2020-07-23
    • 2011-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多