TransWikia.com

MVC C# cerrar sesión y volver atrás

Stack Overflow en español Asked on December 22, 2021

Bien, tengo un aplicativo en MVC C# en el cual el usuario se loguea. Luego viene una pantalla en la que ve sus cosas y tiene el botón de cerrar sesión. El botón para loguearse y desloguearse funciona pero el problema está en el botón back que cuando lo presiono se ve lo siguiente:

introducir la descripción de la imagen aquí

Luego presiono F5:

introducir la descripción de la imagen aquí

Y al presionar continuar se me vuelve a cargar la página del usuario logueado:

introducir la descripción de la imagen aquí

Es decir, al volver atrás se ve esa página en blanco para el re-envío del formulario y al presionar continuar se vuelve a visualizar la vista del usuario. ¿Existe alguna forma de evitarlo? Actualmente mi código es este en el controlador:

public ActionResult Index()
        {
            Response.AppendHeader("Cache-Control", "no-store");
            return View();
        }

        [OutputCache(NoStore = true, Duration = 0, Location = OutputCacheLocation.None)]
        public ActionResult Login(string uname, string psw)
        {
            Response.AppendHeader("Cache-Control", "no-store");
            try
            {
                ConexionSQL sql = new ConexionSQL();
                var caracteres = Convert.ToString(psw);
                var usuario = sql.login(uname, psw);

                if (caracteres == "" || caracteres == null || caracteres.Equals(""))
                {
                    ViewBag.Alert = "Ingrese contraseña.";
                }

                if (usuario.Count <= 0)
                {
                    ViewBag.MensajeUsuario = "El usuario es inexistente.";
                }
                else if (usuario[0].nivel == 0
                    || usuario[0].nivel == 1
                    || usuario[0].nivel == 2
                    || usuario[0].nivel == 7)
                {
                    return View("Login1", usuario);
                }
                else if (usuario[0].nivel == 3
                    || usuario[0].nivel == 4
                    || usuario[0].nivel == 16)
                {
                    return View("Login2");
                }
                else 
                {
                    return View("Index");
                }
            }
            catch (SqlException ex)
            {
                throw ex;
            }
            return View("");
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult LogOff()
        {
            Response.AppendHeader("Cache-Control", "no-store");
        Response.Cache.SetCacheability(HttpCacheability.NoCache);
        Response.Cache.SetExpires(DateTime.Now.AddSeconds(-1));
        Response.Cache.SetNoStore();
        Session.Clear();
        FormsAuthentication.SignOut();
        //return View("Index");
        return RedirectToAction("Index", "Home");
        }
    }

Y este es el código de la vista donde se encuentra el botón cerrar sesión:

@model IEnumerable<ProvidusHomeWeb.Models.Usuarios>

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <meta charset="utf-8">
    <title>Providus</title>
</head>
<body>

    @* Navigation Bar *@

    <div class="topnav">
        <a href="javascript:ruta()">Home</a>
        @using (Html.BeginForm("LogOff", "Home", FormMethod.Post, new { role = "form" }))
        {
            @Html.AntiForgeryToken()
            <button onclick="document.getElementById('id01').style.display='block'" style="width:auto;">Cerrar sesión</button>
        }
        @foreach (var item in Model)
        {
            <label>Bienvenida/o:  @Html.DisplayFor(modelitem => item.usuario)</label>
        }
    </div>
</body>
</html>

Y esta es la vista del index donde se encuentra el form del login:

<!DOCTYPE html>

<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width" />

    <script>
            //Script que impide el uso del botón atrás del navegador
            window.location.hash = "no-back-button";
            window.location.hash = "Again-No-back-button";
            window.onhashchange = function () { window.location.hash = ""; }
        </script>

    <title>Providus</title>

</head>
<body>

    @* Navigation Bar *@
    <div class="topnav">
        <a href="javascript:ruta()">Home</a>
        <div class="login-container">
            <button onclick="document.getElementById('id01').style.display='block'" style="width:auto;">Login</button>
        </div>
    </div>
    <div id="id01" class="modal">
        <form class="modal-content animate" onsubmit="return control()" method="post" action="@Url.Action("Login", "Home")">
            <div class="imgcontainer">
                <span onclick="document.getElementById('id01').style.display='none'" class="close" title="Close Modal">&times;</span>
                <img src="~/Images/00.png" alt="Avatar" class="avatar">
            </div>

            <div class="container">
                <label for="uname"><b>Usuario:</b></label>
                <input type="text" id="uname" placeholder="Ingrese usuario..." name="uname" onkeypress="return soloLetras(event)">

                <label for="psw"><b>Contraseña:</b></label>
                <input type="password" placeholder="Ingrese contraseña..." id="psw" name="psw" onkeypress="return soloNumeros(event)">

                <button type="submit">Iniciar sesión</button>
            </div>
        </form>
    </div>

    <center><img class="img" src="~/Images/00.png" /></center>
    <center><p>Bienvenida/o, por favor inicie sesión.</p></center>

    <script>
        function control() {
            if (document.getElementById('uname').value == null
                || document.getElementById('uname').value == "") {
                alert("El campo no puede estar vacío.");
                document.getElementById('uname').focus();
                return false;
            }
            else if (document.getElementById('psw').value == null || document.getElementById('psw').value == "") {
                alert("El campo no puede estar vacío.");
                document.getElementById('psw').focus();
                return false;
            }
            return true;
        }
    </script>

    <center>
        <p>@ViewBag.Usu</p>
        <p>@ViewBag.Contra</p>
    </center>
</body>
</html>

Global.asax:

protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }

        protected void Application_BeginRequest()
        {
            Response.Cache.SetCacheability(HttpCacheability.NoCache);
            Response.Cache.SetExpires(DateTime.UtcNow.AddHours(-1));
            Response.Cache.SetNoStore();
        }

2 Answers

Tuve este problema en el pasado con php, pero la solución que encontré es general, así que espero lo puedas adaptar para MVC.

En primer lugar esto es una característica del navegador, por lo cual es un poco complejo de tratar.

En la respuesta anterior mencionan una solución en javascript, que igual intenté en su momento, pero la verdad no es optima ya que la pagina puede verse de igual manera por unos segundos hasta que se carga la etiqueta de javascript que ejecuta la acción, además si estás apretando el botón de volver atrás como un desquiciado igual podrás ver el contenido. Otro problema que me encontré en el pasado para esa solución es que si deshabilitas la carga de javascript en el navegador y luego vuelves atrás igual podrás ver el contenido (A no ser que sea una SPA o aplicación similar que compruebe que javascript esté habilitado en el navegador).

La mejor solución que encontré en esos momentos fue limitar la carga de caché mediante headers aplicados en un middleware (DESDE EL BACK-END), esto puede hacer tu sitio más lento al no utilizar el cache, por lo cual debes utilizarlo solo en puntos estratégicos (Como el logout).

Los headers eran los siguientes (basados en php):

 header('Last-Modified:'.gmdate('D, d M Y H:i:s').'GMT');
 header('Cache-Control: no-store, no-cache, must-revalidate');
 header('Cache-Control: post-check=0, pre-check=0',false);
 header('Pragma: no-cache');

La solución en JavaScript:

<script type="text/javascript">
    if(history.forward(1)){
        location.replace( history.forward(1) );
    }
</script>

Answered by Soy César Mora on December 22, 2021

Es más práctico deshabilitar las acción hacia atrás

    <script>
    //Script que impide el uso del botón atrás del navegador
    window.location.hash = "no-back-button";
    window.location.hash = "Again-No-back-button";
    window.onhashchange = function () { window.location.hash = ""; }

    </script>

Answered by Max Paredes on December 22, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP