web-dev-qa-db-fra.com

Avertissement de délai de session dans ASP.NET

J'ai un site asp.net dont j'ai besoin qu'une fenêtre contextuelle/couche/alerte se produise lorsque la session atteint son délai d'expiration (disons 10 minutes). La fenêtre contextuelle indiquera que votre session de compte va expirer pour cause d'inactivité et comporter un bouton pour continuer la session ou un bouton pour la déconnexion.

Je vois différentes façons de le faire en ligne, mais quel est le meilleur moyen de gérer cela? Dois-je mettre un délai supplémentaire si le popup est ouvert trop longtemps?

13
cdub

Consultez cet article, il contient tout ce dont vous avez besoin pour vos besoins. 

Délai de session d'alerte dans ASP.NET

<script language="javascript" type="text/javascript">
       var sessionTimeoutWarning = 
    "<%= System.Configuration.ConfigurationSettings.AppSettings
    ["SessionWarning"].ToString()%>";
        var sessionTimeout = "<%= Session.Timeout %>";

        var sTimeout = parseInt(sessionTimeoutWarning) * 60 * 1000;
        setTimeout('SessionWarning()', sTimeout);

        function SessionWarning() {
var message = "Your session will expire in another " + 
    (parseInt(sessionTimeout) - parseInt(sessionTimeoutWarning)) + 
    " mins! Please Save the data before the session expires";
alert(message);
        }
</script>
23
Pranay Rana

Cela a déjà été résolu, par exemple . ASP.NET - Javascript timeOut Avertissement basé sur sessionState timeOut dans web.config

Toutefois, autant que je sache, il n'y a pas de moyen totalement fiable de le faire, car:

  • Si l'utilisateur a plus d'une fenêtre ouverte en utilisant la même session, une fenêtre peut être plus récente que l'autre et les délais d'expiration de la session client sur la fenêtre la plus ancienne sont périmés/incorrects.
  • Si vous effectuez un aller-retour sur le serveur pour voir quelle est l'expiration de la session en cours, vous l'étendez, ce qui annule l'objectif de la fenêtre contextuelle/alerte.
4
StuartLC

Je suis allé voir l'article de post de Pranay Rana , et j'aime bien l'idée générale, mais le code pourrait être simplifié. Alors voici ma version. Pour les problèmes de tablette/mobile, voir ci-dessous:

<script language="javascript" type="text/javascript">
    var minutesForWarning = 4;
    var sessionTimeout = parseInt("@Session.Timeout"); // razor syntax, otherwise use <%= Session.Timeout %>
    var showWarning = true;

    function SessionWarning() {
        showWarning = false;
        alert("Your session will expire in " + minutesForWarning + " mins! Please refresh page to continue working.");
        // leave a second for redirection fct to be called if expired in the meantime
        setTimeout(function () { showWarning = true; }, 1000);
    }

    function RedirectToWelcomePage() {
        if (showWarning)
            alert("Session expired. You will be redirected to welcome page.");
        document.getElementById('logoutForm').submit();
        // window.location = "../Welcome.aspx"; // alternatively use window.location to change page
    }

    setTimeout('SessionWarning()', (sessionTimeout - minutesForWarning) * 60 * 1000);
    setTimeout('RedirectToWelcomePage()', sessionTimeout * 60 * 1000);
</script>

Eh bien, sur les tablettes ou les téléphones portables, vous ne pouvez pas compter sur setTimeout, car l'exécution de javascript est suspendue lorsque l'appareil est verrouillé ou le navigateur inactif. Au lieu de cela, je fais un contrôle périodique (dans mon cas, j'estime que toutes les 10 secondes suffisent):

<script language="javascript" type="text/javascript">
    function addMinutes(date, minutes) {
        return new Date(date.getTime() + minutes * 60 * 1000);
    }
    function remainingMinutes(date) {
        return Math.round((date - (new Date()).getTime()) / 60 / 1000);
    }

    var minutesForWarning = 5;
    var sessionTimeout = parseInt("@Session.Timeout");
    var showWarning = true;
    var showRedirect = true;
    var timeToWarn = addMinutes(new Date(), sessionTimeout - minutesForWarning);
    var timeToEnd = addMinutes(new Date(), sessionTimeout);

    function CheckTime() {
        if (showWarning && new Date() > timeToWarn && new Date() < timeToEnd) {
            showRedirect = false;
            showWarning = false;
            alert("Your session will expire in " + remainingMinutes(timeToEnd)) + " mins! Please refresh page to continue working.");
        }
        if (new Date() > timeToEnd) {
            if (showRedirect)
                alert("Session expired. You will be redirected to welcome page ");
            document.getElementById('logoutForm').submit();
            // window.location = "../Welcome.aspx"; // alternatively use window.location to change page
        }
        if (showRedirect == false)
            showRedirect = true;
    }

    setInterval(CheckTime, 10000);

</script>
1
Damian Vogel

Vous trouverez ci-dessous un script JavaScript avec jQuery pour avertir l'utilisateur du délai d'expiration de l'authentification des formulaires ASP.NET et les rediriger vers la page de connexion si le délai est atteint. Il pourrait également être amélioré et adapté pour le délai d'expiration de session. Il réinitialisera également le délai d’authentification en "interrogeant" le serveur chaque fois que l’utilisateur interagit avec la page en cliquant, en tapant ou en redimensionnant. 

Notez que cela ajoute de la charge au serveur en effectuant une commande ping à chaque clic, en appuyant sur une touche, en redimensionnant mais c'est assez minime. Néanmoins, si vous avez beaucoup d'utilisateurs en train de taper, vous devrez évaluer l'impact. Je ne pouvais pas penser à un autre moyen de faire cela parce que le serveur doit être impliqué car c'est là que le délai d'attente expire. 

Notez également que le délai d'attente n'est pas codé en dur dans le JS. C'est le délai d'attente du serveur, vous n'avez donc qu'à le conserver à un endroit dans Web.config.

(function ($, undefined) {

    if (!window.session) {

        window.session = {

            monitorAuthenticationTimeout: function (redirectUrl, pingUrl, warningDuration, cushion) {

                // If params not specified, use defaults.
                redirectUrl = redirectUrl || "~/Account/Login";
                pingUrl = pingUrl || "~/Account/Ping";
                warningDuration = warningDuration || 45000;
                cushion = cushion || 4000;

                var timeoutStartTime,
                    timeout,
                    timer,
                    popup,
                    countdown,
                    pinging;

                var updateCountDown = function () {
                    var secondsRemaining = Math.floor((timeout - ((new Date()).getTime() - timeoutStartTime)) / 1000),
                        min = Math.floor(secondsRemaining / 60),
                        sec = secondsRemaining % 60;

                    countdown.text((min > 0 ? min + ":" : "") + (sec < 10 ? "0" + sec : sec));

                    // If timeout hasn't expired, continue countdown.
                    if (secondsRemaining > 0) {
                        timer = window.setTimeout(updateCountDown, 1000);

                    }
                    // Else redirect to login.
                    else {
                        window.location = redirectUrl;
                    }
                };

                var showWarning = function () {
                    if (!popup) {
                        popup = $(
                            "<div style=\"text-align:center; padding:2em; color: black; font-color: black; background-color:white; border:2px solid red; position:absolute; left: 50%; top:50%; width:300px; height:120px; margin-left:-150px; margin-top:-90px\">" +
                                "<span style=\"font-size:1.4em; font-weight:bold;\">INACTIVITY ALERT!</span><br/><br/>" +
                                "You will be automatically logged off.<br/><br/>" +
                                "<span style=\"font-size:1.4em; font-weight:bold;\" id=\"countDown\"></span><br/><br/>" +
                                "Click anywhere on the page to continue working." +
                            "</div>")
                            .appendTo($("body"));

                        countdown = popup.find("#countDown");
                    }

                    popup.show();
                    updateCountDown();
                };

                var resetTimeout = function () {
                    // Reset timeout by "pinging" server.
                    if (!pinging) {
                        pinging = true;
                        var pingTime = (new Date()).getTime();
                        $.ajax({
                            type: "GET",
                            dataType: "json",
                            url: pingUrl,
                        }).success(function (result) {

                            // Stop countdown.
                            window.clearTimeout(timer);
                            if (popup) {
                                popup.hide();
                            }

                            // Subract time it took to do the ping from
                            // the returned timeout and a little bit of 
                            // cushion so that client will be logged out 
                            // just before timeout has expired.
                            timeoutStartTime = (new Date()).getTime();
                            timeout = result.timeout - (timeoutStartTime - pingTime) - cushion;

                            // Start warning timer.
                            timer = window.setTimeout(showWarning, timeout - warningDuration);
                            pinging = false;
                        });
                    }
                };

                // If user interacts with browser, reset timeout.
                $(document).on("mousedown mouseup keydown keyup", "", resetTimeout);
                $(window).resize(resetTimeout);

                // Start fresh by reseting timeout.
                resetTimeout();
            },
        };
    }

})(jQuery);

Appelez simplement ce qui précède une fois votre page chargée:

window.session.monitorAuthenticationTimeout(
        "/Account/Login",    // You could also use "@FormsAuthentication.LoginUrl" in Razor.
        "/Account/Ping");

Sur le serveur, vous aurez besoin d’une action qui renvoie le temps restant. Vous pouvez également ajouter plus d'informations.

    public JsonResult Ping()
    {
        return Json(new { 
                        timeout = FormsAuthentication.Timeout.TotalMilliseconds 
                    }, 
                    JsonRequestBehavior.AllowGet);
    }
1
moomoo

Vous devrez utiliser la technologie côté client pour ici (javascript). En utilisant par exemple, vous utiliseriez javascript timeout facility, puis affichez l'avertissement. Si l'utilisateur clique sur OK, vous pouvez avoir besoin de faire quelque chose pour garder la session en vie. Je voudrais utiliser la méthode jquery.ajax et faire un appel au serveur peut être un faux appel - il suffit de garder la session active.

0
Joseph Caruana

Vous pouvez utiliser jquery et la fonction setinterval pour créer une publication Ajax en coulisse afin d'actualiser le délai, si vous utilisez l'expiration glissante, ou pour obtenir la valeur du temps restant en enregistrant l'heure de début de la session et en soustrayant celle-ci.

0
Chev

ce que vous pouvez faire, c'est utiliser du javascript pour envoyer le message. Utilisez une minuterie pour démarrer après une certaine période (délai défini pour l'expiration de la session dans votre application - quelques minutes). Après cette période, indiquez un message de confirmation à l'utilisateur pour l'expiration de la session. Si l'utilisateur clique pour conserver la session. Créez une publication factice dans la page afin que la session ne soit pas perdue. Vous pouvez également rappeler pour que l'utilisateur ne soit pas confronté à un flash dans la page.

0
UTHIRASAMY