簡體   English   中英

當用戶會話過期時如何重定向到頁面?

[英]How can I redirect to a page when the user session expires?

我目前正在開發一個使用 ASP.NET 2.0 框架的 Web 應用程序。 當用戶會話過期時,我需要重定向到某個頁面,比如 SessionExpired.aspx。 項目中有很多頁面,因此在站點的每個頁面上添加代碼並不是一個很好的解決方案。 不過,我有 MasterPages,我認為這可能會有所幫助。

謝謝!

當用戶“登錄”時,我通常會在母版頁上的 Page.Header.Controls 集合中添加一個 HtmlMeta 控件。 使用適當的超時長度將其設置為 Refresh 到您的 SessionExpired.aspx 頁面,您就可以開始了。

您可以在 Session_Start 事件中的 global.asax 中處理此問題。 您可以在那里檢查請求中的會話 cookie。 如果會話 cookie 存在,則會話已過期:

   public void Session_OnStart()
    {
        if (HttpContext.Current.Request.Cookies.Contains("ASP.NET_SessionId") != null)
        {
            HttpContext.Current.Response.Redirect("SessionTimeout.aspx")
        }

    }

唉,我還沒有找到任何優雅的方式來找出會話 cookie 的名稱。

如果我理解正確,“Session_End”在內部觸發並且沒有與之關聯的 HTTP 上下文:

http://forums.asp.net/t/1271309.aspx

因此,我認為您不能使用它來重定向用戶。 我看到其他人建議在 global.ascx 文件中使用“Session_OnStart()”事件:

http://forums.asp.net/p/1083259/1606991.aspx

我還沒有嘗試過,但是將以下代碼放在“global.ascx”中可能對您有用:

void Session_OnStart() {
    if (Session.IsNewSession == false )
    {
    }
    else 
    {
        Server.Transfer("SessionExpired.aspx", False);
    }
}

我們使用 Forms Authentication 並在 Page_Load 方法中調用此方法

private bool IsValidSession()
    {
        bool isValidSession = true;
        if (Context.Session != null)
        {
            if (Session.IsNewSession)
            {
                string cookieHeader = Request.Headers["Cookie"];
                if ((null != cookieHeader) && (cookieHeader.IndexOf("ASP.NET_SessionId") >= 0))
                {
                    isValidSession = false;
                    if (User.Identity.IsAuthenticated)
                        FormsAuthentication.SignOut();
                    FormsAuthentication.RedirectToLoginPage();
                }
            }
        }
        return isValidSession;
    }

另一種方法是告訴瀏覽器在一定時間后重定向自己(通過 javascript)……但這總是可以被用戶停用。

您無法在會話過期時重定向用戶,因為沒有瀏覽器請求重定向:

  • 如果用戶在會話超時(默認為 20 分鍾)內訪問您的站點,則會話尚未結束,因此您無需重定向他們。
  • 如果用戶在會話超時后訪問您的站點,則會話已經結束。 這意味着它們將處於新會話的上下文中 - Session_OnEnd 已經為舊會話觸發,而您將獲得新會話的 Session_OnStart。

除了客戶端功能(例如 JavaScript 計時器等),您因此需要在 Session_OnStart 中處理重定向 - 但顯然您需要將其與重新訪問該站點的人區分開來。 一種選擇是在會話開始時設置會話 cookie(即沒有過期的 cookie,因此它只持續到瀏覽器關閉),然后在 Session_OnStart 中查找該 cookie - 如果它存在,則它是一個已過期的返回用戶會話,如果不是,則為新用戶。

顯然,您仍然可以使用 Session_OnEnd 在服務器端進行整理 - 這只是您無法使用的客戶端交互。

您是否在 Session 對象中放置了應該始終存在的內容? 換句話說,如果他們登錄,您可能會在會話中放入類似 UserID 的內容

Session("UserID") = 1234

因此,如果是這種情況,那么您可以在母版頁中的代碼隱藏中添加一些內容來檢查該值。 像這樣的東西:

Dim UserID As Integer = 0
Integer.TryParse(Session("UserID"), UserID)

If UserID = 0 Then
  Response.Redirect("/sessionExpired.aspx")
End If

您還可以查看以下鏈接中提供的解決方案

在 ASP.NET 中檢測會話超時並重定向到登錄頁面

添加或更新您的 Web.Config 文件以包含以下內容或類似內容:

<customErrors defaultRedirect="url" mode="RemoteOnly">
    <error statusCode="408" redirect="~/SessionExpired.aspx"/>
</customErrors>

您是否希望在沒有用戶干預的情況下重定向下一個請求,或立即重定向? 如果您希望在沒有用戶干預的情況下進行重定向,那么您可以在母版頁上使用 ClientScript.RegisterStartupScript 來注入一些 javascript,以便在客戶端會話到期時重定向您的客戶端。

    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    String timeoutPage = "SessionExpired.aspx"; // your page here
    int timeoutPeriod = Session.Timeout * 60 * 1000;

    sb.AppendFormat("setTimeout(\"location.href = {0};\",{1});", timeoutPage, timeoutPeriod);
    Page.ClientScript.RegisterStartupScript(this.GetType(), "timeourRedirect", sb.ToString(), true);

代碼從這里

namespace PAB.WebControls

{ 使用系統; 使用 System.ComponentModel; 使用 System.Web; 使用 System.Web.Security; 使用 System.Web.UI;

[DefaultProperty("Text"),

    ToolboxData("<{0}:SessionTimeoutControl runat=server></{0}:SessionTimeoutControl>")]

public class SessionTimeoutControl : Control
{
    private string _redirectUrl;

    [Bindable(true),
        Category("Appearance"),
        DefaultValue("")]
    public string RedirectUrl
    {
        get { return _redirectUrl; }

        set { _redirectUrl = value; }
    }

    public override bool Visible
    {
        get { return false; }

    }

    public override bool EnableViewState
    {
        get { return false; }
    }

    protected override void Render(HtmlTextWriter writer)
    {
        if (HttpContext.Current == null)

            writer.Write("[ *** SessionTimeout: " + this.ID + " *** ]");

        base.Render(writer);
    }


    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);

        if (this._redirectUrl == null)

            throw new InvalidOperationException("RedirectUrl Property Not Set.");

        if (Context.Session != null)
        {
            if (Context.Session.IsNewSession)
            {
                string sCookieHeader = Page.Request.Headers["Cookie"];

                if ((null != sCookieHeader) && (sCookieHeader.IndexOf("ASP.NET_SessionId") >= 0))
                {
                    if (Page.Request.IsAuthenticated)
                    {
                        FormsAuthentication.SignOut();
                    }

                    Page.Response.Redirect(this._redirectUrl);
                }
            }
        }
    }
}

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM