elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Trabajando con las ramas de git (tercera parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Desarrollo Web
| | |-+  PHP (Moderador: #!drvy)
| | | |-+  Sistema de Login Seguro
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Sistema de Login Seguro  (Leído 9,237 veces)
GameAndWatch

Desconectado Desconectado

Mensajes: 42


Ver Perfil
Sistema de Login Seguro
« en: 22 Junio 2012, 21:52 pm »

¡Hola! :D
Estoy creando un sistema de login en PHP, pero me ha surgido este problema.
Antes guardaba el login en cookies, pero me acabo de dar cuenta de lo peligroso que puede ser  >:D :¬¬...así que mi pregunta es:
 :huh:¿que sistema es más seguro a la hora de realizar un login? :huh:
Gracias de antemano por la respuesta  :D


En línea

it3r

Desconectado Desconectado

Mensajes: 101



Ver Perfil
Re: Sistema de Login Seguro
« Respuesta #1 en: 23 Junio 2012, 00:12 am »

mira no tengo mucha experiencia en logins, pero se que se hace con sesiones, es decir utilizas la variable $_SESSION[] y en ella vas guardando datos por ejemplo, cuando el usuario introduce el user y pass estos se deben comparar con una base de datos, si estan correctos se escribe en la sesion algun valor como

Código:
 $_SESSION['logeado']=TRUE; 

con eso despues verificas si ya esta logeado con un

Código:
if(!empty($_SESSION['logeado']))

El usuario no podra modificar este dato porque?,, porque el servidor le pasa una cookie al cliente con el nombre de phpsessionid y este solo contiene un id,, cuando el usuario se mete a la página este le manda la cookie phpsessionid al servidor y el servidor busca en sus sessiones activas la que tenga el id que le paso el cliente.Por ende es mas seguro chequear por session que por cookie. (Si me equivoco corrijanme porfa xD).

Saludos


En línea

marko1985

Desconectado Desconectado

Mensajes: 46


Ver Perfil
Re: Sistema de Login Seguro
« Respuesta #2 en: 23 Junio 2012, 02:31 am »

Hola te dejo un código de mi propia cosecha que me da buenos resultados, está adaptado para un proyecto propio que estoy haciendo, pero vamos que lo puedes modificar a tus necesidades. En mi caso hay varios supuestos para hacer redirecciones, pero puedes simplificarlo en dos partes. Una si existe cookie y otra si no existe, dentro de la que no existe, si el usuario ha verificado la casilla de guardar la sesión creo la cookie, ya que si quieres conservar el estado de la sesión al cerrar el navegador es la única forma. Yo lo que hago es genear un identificador lo guardo en la base de datos, y cuándo se vuelve a meter verifico si ese id está en la BBDD. Si te roban la cookie es un problema de todas formas, pero para conservar el estado es la única forma, al menos desde lo que yo conozco. Puedes crear en el registro un sistema de preguntas y respuestas para que en cada login el salga una de las preguntas aleatoriamente y verificar si es ese usuario. Pero cómo todo login puedes poner todas las trabas que quieras. También podrías generar un certificado único para ese usuario, pero estamos en las mismas si te roban el certificado, ¿no?

Código
  1. <?php
  2. require_once "./includes/classes/class.DB_Handler.php";
  3. require_once "./includes/classes/class.User.php";
  4. require_once "./includes/classes/class.Profiles.php";
  5.  
  6. if(isset($_COOKIE['SocialCores'])){
  7. $key = $_COOKIE['SocialCores'];
  8. try{
  9. if($user = User::check_user_cookie($key)){
  10. $_SESSION['user'] = $user;
  11. switch($_SESSION['user']['profiles']){
  12. case 0:
  13. header("Location:./home.php");
  14. break;
  15.  
  16. case 1:
  17. try{
  18. $profiles_data = Profiles::search_user_profiles($_SESSION['user']['id_user']);
  19. while($data = mysql_fetch_array($profiles_data, MYSQL_ASSOC)){
  20. $_SESSION['user']['profiles_data'][] = array(
  21. 'id_profile' => $data['id_profile'],
  22. 'type' => $data['type'],
  23. 'original_id' => $data['original_id'],
  24. 'blocked' => $data['blocked']
  25. );
  26. }
  27.  
  28. $_SESSION['user']['profiles_data']['current_profile'] = $_SESSION['user']['profiles_data'][0];
  29. $profile_data = Profiles::get_profile_data($_SESSION['user']['current_profile']['type'], $_SESSION['user']['current_profile']['id_profile']);
  30. $profile = mysql_fetch_array($profile_data, MYSQL_ASSOC);
  31. $_SESSION['user']['profiles_data']['current_profile']['data'] = $profile;
  32. header("Location:./profile.php");
  33. }
  34. catch(ProfilesException $e){
  35. $_SESSION['authError'] = $e->getMessage();
  36. header("Location:./index.php");
  37. }
  38. break;
  39.  
  40. case 2:
  41. case 3:
  42. case 4:
  43. case 5:
  44. try{
  45. $profiles_data = Profiles::search_user_profiles($_SESSION['user']['id_user']);
  46. while($data = mysql_fetch_array($profiles_data, MYSQL_ASSOC)){
  47. $_SESSION['user']['profiles_data'][] = array(
  48. 'id_profile' => $data['id_profile'],
  49. 'type' => $data['type'],
  50. 'original_id' => $data['original_id'],
  51. 'blocked' => $data['blocked']
  52. );
  53. }
  54. header("Location:./switcher.profile.php");
  55. }
  56. catch(ProfilesException $e){
  57. $_SESSION['authError'] = $e->getMessage();
  58. header("Location:./index.php");
  59. }
  60. break;
  61. }
  62. }
  63. else{
  64. setcookie("SocialCores", $sessionId, time() - 10, "/");
  65. $_SESSION['authError'] = "Sesión expirada, introduzca sus datos";
  66. header("Location:./index.php");
  67. }
  68. }
  69. catch(UserException $e){
  70. $_SESSION['authError'] = $e->getMessage();
  71. header("Location:./index.php");
  72. }
  73. }
  74.  
  75. else if(isset($_POST['email']) && isset($_POST['password'])){
  76. $email=$_POST['email'];
  77. $pass=$_POST['password'];
  78.  
  79. try{
  80. if($user = User::authUser($email, $pass)){
  81.  
  82. $_SESSION['user'] = $user;
  83.  
  84. if(isset($_POST['rec']) && $_POST['rec']="on"){
  85. $sessionId = session_id();
  86. setcookie("SocialCores", $sessionId, time() + (60 * 60 * 24 * 365), "/");
  87. $id_user = $user['id_user'];
  88. User::update_last_access_id($id_user, $sessionId);
  89. switch($_SESSION['user']['profiles']){
  90. case 0:
  91. header("Location:./home.php");
  92. break;
  93.  
  94. case 1:
  95. try{
  96. $profiles_data = Profiles::search_user_profiles($_SESSION['user']['id_user']);
  97. while($data = mysql_fetch_array($profiles_data, MYSQL_ASSOC)){
  98. $_SESSION['user']['profiles_data'][] = array(
  99. 'id_profile' => $data['id_profile'],
  100. 'type' => $data['type'],
  101. 'original_id' => $data['original_id'],
  102. 'blocked' => $data['blocked']
  103. );
  104. }
  105. $_SESSION['user']['profiles_data']['current_profile'] = $_SESSION['user']['profiles_data'][0];
  106. $profile_data = Profiles::get_profile_data($_SESSION['user']['current_profile']['type'], $_SESSION['user']['current_profile']['id_profile']);
  107. $profile = mysql_fetch_array($profile_data, MYSQL_ASSOC);
  108. $_SESSION['user']['profiles_data']['current_profile']['data'] = $profile;
  109. header("Location:./profile.php");
  110. }
  111. catch(ProfilesException $e){
  112. $_SESSION['authError'] = $e->getMessage();
  113. header("Location:./index.php");
  114. }
  115. break;
  116.  
  117. case 2:
  118. case 3:
  119. case 4:
  120. case 5:
  121. try{
  122. $profiles_data = Profiles::search_user_profiles($_SESSION['user']['id_user']);
  123. while($data = mysql_fetch_array($profiles_data, MYSQL_ASSOC)){
  124. $_SESSION['user']['profiles_data'][] = array(
  125. 'id_profile' => $data['id_profile'],
  126. 'type' => $data['type'],
  127. 'original_id' => $data['original_id'],
  128. 'blocked' => $data['blocked']
  129. );
  130. }
  131. header("Location:./switcher.profile.php");
  132. }
  133. catch(ProfilesException $e){
  134. $_SESSION['authError'] = $e->getMessage();
  135. header("Location:./index.php");
  136. }
  137. break;
  138. }
  139. }
  140. else{
  141. switch($_SESSION['user']['profiles']){
  142. case 0:
  143. header("Location:./home.php");
  144. break;
  145.  
  146. case 1:
  147. try{
  148. $profiles_data = Profiles::search_user_profiles($_SESSION['user']['id_user']);
  149. while($data = mysql_fetch_array($profiles_data, MYSQL_ASSOC)){
  150. $_SESSION['user']['profiles_data'][] = array(
  151. 'id_profile' => $data['id_profile'],
  152. 'type' => $data['type'],
  153. 'original_id' => $data['original_id'],
  154. 'blocked' => $data['blocked']
  155. );
  156. }
  157. $_SESSION['user']['profiles_data']['current_profile'] = $_SESSION['user']['profiles_data'][0];
  158. $profile_data = Profiles::get_profile_data($_SESSION['user']['profiles_data']['current_profile']['type'], $_SESSION['user']['profiles_data']['current_profile']['id_profile']);
  159. $profile = mysql_fetch_array($profile_data, MYSQL_ASSOC);
  160. $_SESSION['user']['profiles_data']['current_profile']['data'] = $profile;
  161. header("Location:./profile.php");
  162. }
  163. catch(ProfilesException $e){
  164. $_SESSION['autherror'] = $e->getMessage();
  165. header("Location:./index.php");
  166. }
  167. break;
  168.  
  169. case 2:
  170. case 3:
  171. case 4:
  172. case 5:
  173. try{
  174. $profiles_data = Profiles::search_user_profiles($_SESSION['user']['id_user']);
  175. while($data = mysql_fetch_array($profiles_data, MYSQL_ASSOC)){
  176. $_SESSION['user']['profiles_data'][] = array(
  177. 'id_profile' => $data['id_profile'],
  178. 'type' => $data['type'],
  179. 'original_id' => $data['original_id'],
  180. 'blocked' => $data['blocked']
  181. );
  182. }
  183. header("Location:./switcher.profile.php");
  184. }
  185. catch(ProfilesException $e){
  186. $_SESSION['authError'] = $e->getMessage();
  187. header("Location:./index.php");
  188. }
  189. break;
  190. }
  191. }
  192. }
  193. else{
  194. $_SESSION['authError'] = "Email o contraseña incorrectos";
  195. header("Location:./index.php");
  196. }
  197. }
  198. catch(UserException $e){
  199. $_SESSION['authError'] = $e->getMessage();
  200. header("Location:./index.php");
  201. }
  202. catch(Exception $e){
  203. $_SESSION['authError'] = $e->getMessage();
  204. header("Location:./index.php");
  205. }
  206. }
  207.  
  208. else{
  209. $_SESSION['authError'] = "Debe acceder al sistema através de esta página";
  210. header("Location:./index.php");
  211. }
  212.  

En línea

GameAndWatch

Desconectado Desconectado

Mensajes: 42


Ver Perfil
Re: Sistema de Login Seguro
« Respuesta #3 en: 23 Junio 2012, 08:32 am »

Lo primero:
¡Gracias a los dos por responder! :D :D
Pero tengo una duda con el código. Veo que guardas el id en la BBDD, pero...¿Cuando borras ese id? Lo digo porque si no, se te puede crear una tabla enorme... :-\
En línea

marko1985

Desconectado Desconectado

Mensajes: 46


Ver Perfil
Re: Sistema de Login Seguro
« Respuesta #4 en: 23 Junio 2012, 13:20 pm »

Hola,

Quizás te he dejado a medias con ese código y falta complementarlo. Cómo puedes ver en el script de arriba hago unos includes con una clases que he diseñado para este proposito y que despues también utilizo a lo largo de la aplicacion

En la clase class.User.php existen unos métodos estáticos, uno de estos métodos es check_user_cookie('$key")

Te pongo aquí el código

Código
  1. public static function check_user_cookie($key){
  2. $db = new DB_Handler('localhost', 'MI BASE DE DATOS');
  3. $key = md5($key);
  4. $sql = "SELECT * FROM users WHERE last_valid_sessid = '$key'";
  5. if($query =  mysql_query($sql, $db->link)){
  6. $user = mysql_fetch_array($query);
  7. return $user;
  8. }
  9. else{
  10. return false;
  11. }
  12. }
  13.  

Cómo puedes ver busco en la tabla usuarios un campo que he llamado last_valid_sessid con el valor $key, cuándo se crea la cookie por primera vez este valor se guarda en un campo llamado last_valid_sessid, cuándo vuelva ha acceder se sobreescribe con un nuevo valor. no guardar los ID de las sesiones en ningún sitio diferente sino que va asociado a un campo de la tabla usuarios, que puedes establecer desde un inicio como valor Null te pongo un pantallazo de la tabla.



No sé si me he explicado bien,

El flujo sería:

LEO COOKIE -> BUSCO VALOR EN BBDD -> SI EXISTE VALIDO LA SESIÓN -> SOBREESCRIBIMOS COOKIE Y BBDD CON UN NUEVO ID.

Yo lo tengo muy liado con mis clases y mis historias pero más o menos sería así.

Un saludo.
En línea

GameAndWatch

Desconectado Desconectado

Mensajes: 42


Ver Perfil
Re: Sistema de Login Seguro
« Respuesta #5 en: 23 Junio 2012, 14:28 pm »

Ahora sí que lo entiendo :D

 ;-) ;-)¡¡Muchas gracias!! ;-) ;-)

Con PHP había mis cosas internas, pero nunca había hecho nada de login (bueno, he hecho 2 pero con cookies) ;)


En línea

marko1985

Desconectado Desconectado

Mensajes: 46


Ver Perfil
Re: Sistema de Login Seguro
« Respuesta #6 en: 23 Junio 2012, 17:02 pm »

De nada.

De todas formas yo quería algo muy específico, y es probable que tenga fallos, he intentado hacerlo seguro, pero aquí hay verdaderos expertos en seguridad que estrujarían mi código rápidamente. Aún así te recomiendo encarecidamente que cuándo tengas más por la mano PHP uses algún Framework ya que facilitan mucho el trabajo para estas tareas comunes.

Te pongo algunos de los más comunes

Zend Framework (de los creadores de PHP)
Symphony
Cake
CodeIgniter 2 (Yo estoy empezando con este ahora)

Saludos, cualquier cosa en la que se pueda ayudar ya sabes...
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Sistema de login.
PHP
lnvisible 4 3,016 Último mensaje 1 Diciembre 2011, 04:33 am
por #!drvy
¿Qué tan seguro es este login que he planteado en un sitio web en ASP.Net?
Desarrollo Web
TwisteD420 4 4,899 Último mensaje 4 Abril 2012, 02:42 am
por TwisteD420
Login seguro para desarrollo web
Seguridad
vctr89 0 2,809 Último mensaje 16 Agosto 2013, 18:29 pm
por vctr89
Sistema de login muy seguro « 1 2 3 »
.NET (C#, VB.NET, ASP)
TomaSs 22 15,112 Último mensaje 25 Octubre 2013, 13:52 pm
por eferion
Sistema de login muy seguro
Ingeniería Inversa
TomaSs 2 3,084 Último mensaje 26 Septiembre 2013, 19:09 pm
por TomaSs
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines