Login de Usuario -> JSP/Servlet | EDITADO

Editado: Hoy en la mañana, completé las partes que… faltaban :D

Lo principal, fueron los errores. En la versión 1, no se informaban de ellos. Ahora sip :D Además, ordené un poco el código (nunca esta de más ;) )
Pueden ver los cambios aquí. Y el post completo después del salto.
Eso si, el post sigue igual. :P

Así es! Luego de varios días, logré hacer el login. Lo mismo que iba a hacer hace unos cuantos post atrás en PHP, ps ahora viene en Java :P

Funciona de esta manera (como para que se hagan la idea de lo que van a ver ;) ) :

  1. Cargamos la página (.jsp) y pedimos el nombre de usuario, y la contraseña.
  2. Usando JavaScript, encriptamos la contraseña en MD5 (es más seguro encriptarla desde el cliente)
  3. Enviamos la contraseña encriptada al servlet, y la comparamos con la que tenemos en la BD
  4. Si todo funciona como debe (previas validaciones), mostramos la página del admin (por ahora del admin, luego viene de los trabajadores, etc).

Manos a la obra (o como dicen algunos… al código x.X)

Entonces, en nuestro archivo jsp, solamente tenemos esto:

  • El linkeo al archivo .js para encriptar:
    <script type="text/javascript" src="MD5.js"></script>

    Como leen, lo tengo en la misma carpeta. Depende de donde lo tengan ustedes, y ps le hacen el cambio.

  • Un form, que tiene el campo para el nombre de usuario, la pass, y uno para que vean la pass encriptada.
    <form action="/ConectaBD/login" method="post">
                Nombre de Usuario:<input type="Text" name="nombre" size="20"><br />
                Contraseña: <input type="Password" name="pass" onkeyup="this.form.hash.value = MD5(this.form.pass.value)"><br />
                MD5 Generado: <input type="text" name="hash" value="" style="width: 336px;" /><br />
                <input type="submit" name="envio" value="Enviar">
            </form>

Pueden ver el código completo de este archivo en pastebin

Ahora, el servlet login. Estuve toda la tarde haciendo el famoso archivito, pero logré completarlo. Puede que no sea perfecto, pero es una base ;)

Los import necesarios (además de los que ya vienen) son:

import javax.servlet.http.*;
import java.sql.*;

Variables de Clase:

private String nombre, pass, //En pass se guarda la que ingreso el usuario
            AttNombre ="", AttAppe ="", //Para guardar los datos que nos regrese la BD
            SQLEx = "", EX = ""; //Los errores que podamos tener 

Empezamos con  el método doPost. El doGet si gustan pueden borrarlo, no lo vamos a usar.

public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        HttpSession sesion = request.getSession(true);
        this.validar(request.getParameter("nombre"), request.getParameter("hash"));
        sesion.setAttribute("nombre", this.AttNombre);
        sesion.setAttribute("ape", this.AttAppe);

        response.sendRedirect(response.encodeRedirectURL("/ConectaBD/postLog.jsp") );
    }

Lo primero que hacemos, es crear una sesión para el usuario.
Luego llamamos a la función validar para que valide los campos (le enviamos los datos ingresados por el usuario). Fíjense que estoy tomando el texto del input “hash”, porque las contraseñas las tengo encriptadas en la BD.
Después de que “validar” cumpla su trabajo (que veremos más adelante),  guardamos, como variables de sesión, el nombre y el apellido de la persona. (Nosotros ingresamos solo el nombre de usuario.)
Por último, vamos al archivo “postLog.jsp”.

Veamos que hace “validar” :

private void validar(String parNom, String parPass){
        Boolean estado = false;
        String falta = null;

        if(!parNom.isEmpty()){
            if(!parPass.isEmpty()){
                estado = true;
                this.nombre = parNom;
                this.pass = parPass;
            }else{ falta = "No se ingresó la Contraseña";
        }else{ falta = "No se ingresó el Nombre de Usuario"; }

        this.lectorBD(estado, falta);
    }
  • Fijamos una variable tipo Boolean para definir el estado, y “falta” para guardar un mensaje.
  • Si parNom NO viene vacía, comprobamos que parPass NO venga vacía tampoco.
  • Cuando esto se cumpla, cambiamos el estado a true.
  • En caso de que alguna de ellas esté vacía, guardamos el mensaje correspondiente.
  • Llamamos a la función “lectorBD”

Siguiente -> lectorBD

private void lectorBD(Boolean estado, String aviso){
        if(estado){
            try{
                String MySQLDriver ="com.mysql.jdbc.Driver",
                        DriGetConn = "jdbc:mysql://127.0.0.1/proyec",
                        //El nombre de usuario y la contraseña para entrar a BD
                        userBD = "USUARIOBD", passBD ="CONTRASEÑA-DE-BD",
                        selectID ="SELECT id FROM usernames WHERE username ='",
                        IDpass ="", //El ID de la persona que se loguea
                        selectMD5 ="SELECT password FROM passwords WHERE id ='",
                        passMD5 = "", //La contraseña de la persona leida desde la BD
                        selectDatos ="SELECT nombre, apellido FROM dusuarios WHERE rut='";

                Class.forName(MySQLDriver);
                Connection conexion = DriverManager.getConnection
                        (DriGetConn, userBD, passBD);
                Statement query = conexion.createStatement(
                        ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
                ResultSet rs = query.executeQuery(selectID + nombre +"'");
                rs.first();
                IDpass = rs.getString("id");
                rs.close();
                rs = query.executeQuery(selectMD5 + IDpass + "'");
                rs.first();
                passMD5 = rs.getString("password");
                rs.close();

En esta primera parte hacemos lo siguiente:

  • Si estado viene como true, entramos a leer datos desde la BD.
  • Las variables… son para acortar código simplemente. Ps son entendibles ;)
  • Definimos el Driver para MySQL. Bla bla bla.
  • Después, y como yo tengo definidas mis tablas 8O , buscamos el “id” del “username” ingresado.
  • Con este “id”, buscamos la contraseña del “username” ingresado. Esta contraseña es la que esta guardada en la BD.

En la segunda parte —>

if(this.passMatch(passMD5)){
rs = query.executeQuery(selectDatos + IDpass +"'");
rs.first();
this.AttNombre = rs.getString(1);
this.AttAppe = rs.getString(2);
rs.close();
}
query.close(); conexion.close();
}catch(SQLException ex){
this.SQLEx = "Se produjo una excepción durante la conexión: "+ ex.toString();
}catch(Exception ex){
this.EX = "Se produjo una excepción: "+ ex.toString();
}
}
}
  • Ahora, llamamos a la función passMatch para comprobar que las 2 sean iguales (la que ingresamos en el formulario, y la que leímos desde la BD). La usamos directamente en el “if”. Enviamos como parámetro la contraseña leída desde la BD.
  • Sabemos que son iguales, por lo tanto guardamos en las variables de clase “AttNombre” y “AttAppe” lo que obtenemos desde la BD.
  • Si tenemos error de SQL, captamos la Exception. Lo mismo con otros errores.

Veamos la función “passMatch()”

private Boolean passMatch(String passMD5){
        if(this.pass.equals(passMD5)){
            return true;
        }else{
            return false;
        }
    }
  • Simple :D Comparamos el string entregado por el form, con el string de la BD
  • Si son iguales, retornamos un true.
  • Si no… ps un false x.X

Eso es todo! Pueden ver el código de la clase aquí

Por último, el código de “postLog.jsp”

Primero las leímos:

<%@page session="true" %>
<%String nombres = (String)session.getAttribute("nombre");
   String apellidos = (String)session.getAttribute("ape");%>

Luego las escribimos:

 <body>
        <h2>Tenemos las variables de sesión, que guardamos en el servlet</h2>
        <%=nombres%><br/>
        <%=apellidos%>
    </body>

Ahora si, hemos terminado :D Pueden verlo desde aquí

Faltaría controlar los errores. Osea, los errores están bajo control, faltaría notificar al usuario de ellos :D

Cualquier pregunta, ps ya saben ;) :P

About these ads

Acerca de MaritoCares

Ingeniero Informático. Con tendencias a la programación en [C#, VB].NET, Java(Web principalmente...), PHP, JavaScript, algo mínimo de [ruby, python], y el clásico C.
Esta entrada fue publicada en Proyecto y etiquetada , , . Guarda el enlace permanente.

22 respuestas a Login de Usuario -> JSP/Servlet | EDITADO

  1. nancy dijo:

    Pero, y que hay del md5.js, cual es el código?

    Porque dices que es más seguro encriptar del lado del cliente? Es más dificil que sea interceptado? Esque estoy haciendo mi login con un jsp, y la insercion a la BD y encriptación lo hago con MessageDiggest de una libreria de java en un bean, pero no se que sea más conveniente.

    Saludos y gracias.

    • MaritoCares dijo:

      Tienes razón… xD
      El código que uso lo tomé de aquí

      Imagina que te estas logueando, escribes tu nombre de usuario y la pass.
      Envías tus datos así tal cual y SAS! Alguien atrapa el envío y ve algo como login?usuario=marito&pass=1234

      Si la encriptas antes del envío, en caso que la lleguen a ver solo verán 32 dígitos. Como MD5 encripta para un solo lado, ps están sonados ;) Y no podrían “desEncriptarla”

      De todas formas, puedes encriptar la encriptada como dices ;)
      Saludos :)

  2. kulmino dijo:

    Hola! espero que todavia estes en esta web activo por que tengo un problema al querer ejecutar esto que subiste. Es muy interesante y encima es justo lo que necesito jeje

    Saludos

  3. lahernandez dijo:

    Hola Mario:

    Leyendo tu post, me di cuenta que me serviria mucho ,pero tengo una pregunta. Lo que necesito es un servlet que valide el usuario y la contraseña de una pagina jsp1 para pasar a otra pagina jsp2, como te comento tu solución me ayuda pero esto serviría para que no puedan ingresar al jsp2 aprendiendome la ruta de ese jsp2 y teclearla directamente en el browser?
    Gracias

    • MaritoCares dijo:

      Fácil!

      En mi página postLog.jsp tengo

      <%@page session="true" %>
      <%String nombres = (String)session.getAttribute("nombre");
         String apellidos = (String)session.getAttribute("ape");%>

      Qué pasa si me salto la validación y entro directamente? El servidor entrega un error. Si te fijas, en el servlet guardo (en variables de sesion) datos de la persona. Si no me valido, no llamo al servlet y por lo tanto las variables no se llenan.

      Cuando entre al postLog.jsp, el servidor las va a leer, pero al no tener nada va a entregar un error de vacío :D

      Podrías hacerlo más delicado avisando al usuario o redirigiendo a la página principal, pero con el solo hecho de que el servidor te bloquee la entrada (por un error) es una forma de seguridad.
      :P

  4. RAFAael dijo:

    hola amigos estoy haciendo un programa para consultar las notas de un alumno
    les explico .el alumno el padre de familia el profesor y la secreatria de un colegio tienen q logearse para poder entrar a la pagina osea el profesor y la secretaria puden modificar notas y e alumno y padre de falia solo consultar notas el programa lo estoy ahciendo en netbeans .6.8 pero no se como hacerlo pork cuando el alumno se logea automaticamente tiene q ver sus notas ps no se como ahcerlo .no se como hacer eso
    bueno les agradesco su ayuda

  5. MaritoCares dijo:

    Hombre todo está en las variables de sesión!

    Imaginemos que tienes una BD; y en ella, en el maestro de usuarios tienes los distintos permisos. Por ejemplo:

    Secretaria Permiso escritura
    Profesor Permiso escritura
    Alumno Permiso Lectura
    Padre Permiso Lectura

    Ahora, cuando inicias sesión en el sistema lees en la BD cuál es el tipo de permiso que tiene el usuario que se ha conectado.

    De ser escritura o lectura haces el control y muestras tal y tal pantalla :D Es simple de hacer, quizás algo difícil de entender x_X

  6. Merylinda dijo:

    Hola Marito!!
    Espero todavía andes por esta web!
    Oye muy interesante el ejemplo que muestras, soy novata en esto de java… seguí tu ejemplo, pero me sale un error, como si el método post del form no encontrara la clase login, cuando dices “/ConectaBD/login” esta ruta a que se refiere…??, yo tengo mi archivo login en un paquete llamado Servlets pero me sale el error: HTTP Status 404 –

    ——————————————————————————–

    type Status report

    message

    descriptionThe requested resource () is not available.

    ——————————————————————————–

    GlassFish Server Open Source Edition 3.1

    • MaritoCares dijo:

      Hola!

      Me demoro su poco, pero nunca lo dejo de lado ;)

      Con /ConectaBD/login me refiero a: /Aplicacion/Servlet

      Lo otro, no puedes entrar a una “clase” a menos que sea un extend de HttpServlet.

      Y Claro, todo depende de como tengas configurado tu servidor y las rutas de cada servlet.

      Cualquier cosa, me preguntas por Twitter (respondo mas rapido por ahi)

  7. Anónimo dijo:

    AMIGO SI VES ESTO PODRIAS AYUDARME

  8. Anónimo dijo:

    amigo buenas noches si pudieras ayudarme con esto que me sirve para un proyecto

  9. amigo tengo unos problemas con la conexion a la bd si me pudieras ayudar

  10. alexander dijo:

    Hey masiso, haber si andas aun por aca, estaba viendo tu post y me parecio muy util. pero tengo una pregunta, soy nuevo en jsp y me eh quedado en algo que talves sea sencillo para vos. bueno aqui va. la cosa esta en que estoy tratando de hacer un login bien validado, tengo el usuario cargado en un combobox y el password en un input, se elige el usuario(cargado desde la bd) y se escribe la contraseña, ahora, si deja el campo de password vacio le tira una alerta diciendole que la escriba (esa alerta es una funcion de un archivo .js que la llamo), por ahora bien, pero digamos escribe mal la contraseña, aqui va la otra validacion, en ese mismo instante cuando presiona el boton ‘iniciar’ verifica si el usuario y la contraseña estan en la bd, pero como dije, el combobox carga todos los usuarios desde la bd y lo que quiero es que si la contraseña es incorrecta le tire la alerta asi como lo hice si dejaba el campo password vacio, la cosa es que me eh quedado sin ideas y no se como mandar a llamar a la funcion nouser en jsp. aqui te muestro el codigo:

    - aqui va el cbbox y el input del password, los archivos de conexion a la bd y las inclusiones de scripts ya estan hechas, por otro lado, tambien utilizo sertvelts y clases para la recuperacion de datos.
    NOTA: script1.js es la validacion de campo password vacio, y script2 es la validacion de que si existe o no la contraseña en la bd.

    <%
    Connection canal = null;
    ResultSet tabla= null;
    Statement instruccion=null;

    try {
    Class.forName("com.mysql.jdbc.Driver").newInstance();
    canal=DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/ct_systembdd","root","");
    instruccion = canal.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
    ResultSet.CONCUR_UPDATABLE);
    } catch(java.lang.ClassNotFoundException e){} catch(SQLException e) {};

    try {
    tabla = instruccion.executeQuery("select usuario from tipo_usuario order by usuario");
    } catch(SQLException e) {};
    //administrador y root son usuarios del sistema.
    out.println("
    AdministradorRoot”);
    while(tabla.next()) {
    out.print(“”+tabla.getString(1)+””);
    };
    out.print(“”);
    tabla.close();instruccion.close();canal.close();
    %>

    - aqui esta el sertvlet

    Resultado de prueba del uso de beans

    - y aqui esta el script2.js

    function nouser(log){
    if(log.pa.value != agapas){
    window.alert(‘ALERTA: Password incorrecto.’);
    log.pa.focus();
    return false;
    }else{
    return true;
    }
    }

    Mi talon de aquiles es simple, puse todo esto para que me entendieras lo que trato de hacer, no puedo y no se como mandar a llamar a la funcion nouser del script2 en esta parte
    else {
    //aqui es donde quiero mandar a llamar al script2.js de verificacion de password
    //response.sendRedirect(“no encontrado”);
    }
    porfavor, si puedes ayudadarme te lo agradeceria muchisimo! :)

  11. MaritoCares dijo:

    No puedes llamar funciones javascript desde un servlet, a menos que lo hagas por ajax…

    En ese caso, busca en mi blog que tengo varias funciones en ajax :D

    Pero más menos es algo así:

    1. Llamas al servidor y le envías los datos por GET o POST
    2. El servidor hace las cosas y te responde con un Si o un No
    3. Lees la respuesta y dependiendo de ella muestras o no el mensaje :D

  12. Anónimo dijo:

    Brother! un exito tu blog!!! saludos (Y)!

  13. Remy dijo:

    Gracias me sirvio mucho tu ejemplo… solo me quedo una duda en mi caso necesito pasar unos datos por lo cual los necesito encriptarlos. Lo que puede lograr gracias a tu post.
    ¿Pero ahora tengo que desencriptarlo en la página a los que los envio?
    Saludos

    • MaritoCares dijo:

      Depende de cómo lo estés trabajando.
      En el caso del post es la contraseña la que se encripta por MD5. Y como sabemos. MD5 trabaja sólo en 1 sentido. La contraseña en mi BD se encuentra encriptada, por lo que la comparación es simple entre strings.

      Si quieres encriptar y desencriptar, tendrías que trabajar con una llave, cosa que nunca he hecho en Java :D

  14. Anónimo dijo:

    como es que llamas a la clase esa???

Deja un comentario

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s