2012-02-16 48 views
5

Tengo un problema con las cookies en MVC3. Quiero crear una cookie, que almacene información si el usuario ha iniciado sesión. Nunca he usado cookies antes y no sé cuál es la manera correcta de hacerlo y soy nuevo en MVC3. Por favor, ¿alguien puede decirme si el enfoque que utilicé para almacenar cookies es correcto o si existe algún riesgo de seguridad (la contraseña está encriptada)? Si las cookies están configuradas correctamente, ¿cómo puedo usarlas en otras vistas para verificar si el usuario está conectado y configurar la sesión para él? Si el enfoque que uso para iniciar sesión es incorrecto, solo dígame.Crear y leer cookies para confirmar el usuario conectado en C# MVC3

public ActionResult Login(string name, string hash, string keepLogged) 
    { 
     if (string.IsNullOrWhiteSpace(hash)) 
     { 
      Random random = new Random(); 
      byte[] randomData = new byte[sizeof(long)]; 
      random.NextBytes(randomData); 
      string newNonce = BitConverter.ToUInt64(randomData, 0).ToString("X16"); 
      Session["Nonce"] = newNonce; 
      return View(model: newNonce); 
     } 

     User user = model.Users.Where(x => x.Name == name).FirstOrDefault(); 
     string nonce = Session["Nonce"] as string; 
     if (user == null || string.IsNullOrWhiteSpace(nonce)) 
     { 
      return RedirectToAction("Login", "Users"); 
     } 

     string computedHash; 
     using (SHA256 sha256 = SHA256.Create()) 
     { 
      byte[] hashInput = Encoding.ASCII.GetBytes(user.Password + nonce); 
      byte[] hashData = sha256.ComputeHash(hashInput); 
      StringBuilder stringBuilder = new StringBuilder(); 
      foreach (byte value in hashData) 
      { 
       stringBuilder.AppendFormat("{0:X2}", value); 
      } 
      computedHash = stringBuilder.ToString(); 
     } 

     if (computedHash.ToLower() == hash.ToLower()) 
     {     
      Session["IsAdmin"] = user.IsAdmin == 1; 
      Session["IDUser"] = user.IDUser; 

      ViewBag.IdUser = IDUser; 
      ViewBag.IsAdmin = IsAdmin; 
      ViewBag.UserName = model.Users.Where(x => x.IDUser == IDUser).First().Name; 

      if (keepLogged == "keepLogged") 
      { 
       //Set user's cookies - is this correct? 
       Response.Cookies.Add(new HttpCookie("UserCookie", user.IDUser.ToString())); 
       Response.Cookies.Add(new HttpCookie("PassCookie", user.Password.ToString())); 
      } 
     } 
     return RedirectToAction("Index", "Posts"); 
    } 
+5

¿Quizás le gustaría usar la autenticación de formularios? –

Respuesta

17

Este código crea una cookie cifrada con el nombre de usuario

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
    1, 
    user.UserName, 
    DateTime.Now, 
    DateTime.Now.AddMinutes(10), 
    false, 
    null); 

string encryptedTicket = FormsAuthentication.Encrypt(ticket); 
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket); 

this.Response.Cookies.Add(cookie); 

Para habilitar la autenticación de formularios añadir lo siguiente a la sección de system.web del web.config:

<authentication mode="Forms"> 
    <forms loginUrl="~/Logon" timeout="2880" /> 
</authentication> 
+0

Gracias por este ejemplo, intentaré esto, ¿puede decirme cómo puedo leer esta cookie en otro método? – Petr

+0

+1, esta sería la forma correcta de manejar su autenticación. – Jesse

+3

Puede verificar si el usuario está autenticado con este código: if (HttpContext.Current.User.Identity.IsAuthenticated) –

4

No, no desea almacenar la contraseña del usuario en una cookie personalizada. Mire en la Authetication de formas. Hace todas las cookies para usted. Puede configurar que las cookies de autenticación de formularios permanezcan en la computadora del usuario para que "permanezcan conectadas".

+0

Si uso la autenticación de formularios, ¿significa que tengo que cambiar el método de inicio de sesión completo? – Petr

+0

Podría conservar el método, pero la mayoría del código podría simplemente reemplazarse según @Vivien Adnot answer – Jesse

4

aquí está mi versión de cómo simlified puede trabajar con las cookies para recordar el nombre de usuario

/// <summary> 
    /// Account controller. 
    /// </summary> 

     public ActionResult LogOn() 
     { 
     LogOnModel logOnModel = new LogOnModel(); 

     HttpCookie existingCookie = Request.Cookies["userName"]; 
     if (existingCookie != null) 
     { 
      logOnModel.UserName = existingCookie.Value; 
     } 

     return View(logOnModel); 
     } 


     public ActionResult LogOn(LogOnModel model, string returnUrl) 
     { 
     if (model.RememberMe) 
     { 
      // check if cookie exists and if yes update 
      HttpCookie existingCookie = Request.Cookies["userName"]; 
      if (existingCookie != null) 
      { 
       // force to expire it 
       existingCookie.Value = model.UserName; 
       existingCookie.Expires = DateTime.Now.AddHours(-20); 
      } 

      // create a cookie 
      HttpCookie newCookie = new HttpCookie("userName", model.UserName); 
      newCookie.Expires = DateTime.Today.AddMonths(12); 
      Response.Cookies.Add(newCookie); 
     } 


     // If we got this far, something failed, redisplay form 
     return View(model); 
     } 
+1

Si bien ha demostrado que puede guardar el nombre de usuario en una cookie, está repitiendo la rueda. La autenticación de formularios se debe utilizar en este escenario. – Jesse

+1

@Jesse: esto fue para demostrar cómo usar cookies – cpoDesign

Cuestiones relacionadas