Foros del Web » Programando para Internet » ASP Clásico »

Un módulo de usuarios

Estas en el tema de Un módulo de usuarios en el foro de ASP Clásico en Foros del Web. Hola a todos, desde hace tiempo he querido ir desarrollando un pequeño módulo que pueda servir a la comunidad, después de indagar un poco y ...

  #1 (permalink)  
Antiguo 28/09/2007, 23:30
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 10 meses
Puntos: 98
Un módulo de usuarios

Hola a todos, desde hace tiempo he querido ir desarrollando un pequeño módulo que pueda servir a la comunidad, después de indagar un poco y aunque hay muchas y muy buenas cosas hechas, y asp 3.0 es obsoleto y bla bla bla, no me quise quedar con las ganas, así que pensé en desarrollar un pequeño módulo de usuarios donde además daré una breve explicacón de las técnicas empleadas y su por qué, espero que lo disfruten y nos acompañemos, estaré muy contento de escuchar/leer sus dudas y sobre todo sus sugerencias, tomen en cuenta que todo lo expresado a lo largo de este tópico es meramente mi opinión, lo importante es obtener cada quien sus conclusiones.


- Sobre la estructura de directorios:
Esto es algo que regularmente todos pasamos por alto a la hora de construír nuestras aplicaciones, y no debería ser; una buena estructura de directorios, nos permite tener organizado nuestros archivos, y contenidos, por ende, el mantenimiento al website siempre será mejor y más organizado, entre más organizado y simple se encuentre nuestra estructura de directorios, así pues que para este proyecto, emplearemos la siguiente estructura:

Código:
Directorio raíz
|
|--admin (la famosa carpeta, ya sabes que es ¿no?)
|
|--componentes (utilizaremos esta carpeta para alojar nuestra/s clase/s)
|
|
|--global.asa
|--conexion.asp
Bueno, hasta aquí vamos bien, pretendo que podamos hacer nuestra aplicación configurable con Access y SQL, hace mucho que no trabajo con Access, pero en teoría debe funcionar igual si nos apegamos a los estándares MS

* Pasos preliminares

Nombre de la base de datos: curso
Estructura:

Código:
tbl_usuario
--------------------
usuario_id           |  autoincremental, llave primaria
usuario_uname   |  texto/varchar(50)
usuario_pwd       |  texto/varchar(50)

* Código del global.asa
Es siempre una buena costumbre utilizar nuestro global.asa de manera eficiente, hay que recordar que el alcance de las variables declaradas en el global.asa, es de aplicación, esto quiere decir que estarán disponibles para toda la vida de nuestra aplicación desde la primera petición que se haga a nuestro sitio web y en adelante; su valor será siempre el mismo a menos que se modifique directamente el global.asa

Código:
<script language="vbscript" runat="server">
sub Application_OnStart
    Application("baseDatos") = "sql" 'cambia valor a access si es esta bd con la que trabajarás
    Application("baseDatosNombre") = "cursito" 'nombre de tu base de datos, la mia se llama cursito
    Application("baseDatosRutaoServidor") = "(local)" 'direccion de tu servidor SQL, o ruta de fisica a tu base de datos si ocupas access, asegurate de ponerle un \ al final de la ruta.
end sub
</script>

* Código del archivo conexion.asp
Esto es algo que personalmente me parece una buena práctica, me gusta guardar el string de conexión en un archivo.asp que llamo conexion.asp, ahí podemos poner ciertas condiciones que se cumplan de acuerdo a nuestra variable de aplicación para hacerle saber qué base de datos utilizará.

Código:
<%
Dim strConnect
Select case lcase(Application("baseDatos"))
    case "access"
        strConnect = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="&Application("baseDatosRutaoServidor")&";"
    case "sql"
        strConnect = "Provider=SQLNCLI;Server="&Application("baseDatosRutaoServidor")&";Database="&Application("baseDatosNombre")&";Trusted_Connection=yes;"
End Select
%>
<!-- METADATA type="typelib" file="D:\program Files\Common Files\System\ado\msado15.dll" -->
Básicamente es un SELECT CASE, el cual se encarga de elegir el string de conexion. Nota el include que hago del archivo msado15.dll, esta es una muy buena práctica para incluir las constantes de ado sin tener que incluir el archivo ese maligno llamado adovb.inc o algo por el estilo, que siempre me cayó mal y lo bueno de tener este archivo de conexion es que lo incluiremos en todos lados donde nos conectemos a la base de datos, por lo tanto, también tendremos nuestras constantes de ADO disponibles cada vez que queramos abrir una conexión.


Eso es todo por hoy, mañana incluiremos nuestro formulario de login y revisaremos lo básico de la clase usuario.

Salud
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #2 (permalink)  
Antiguo 29/09/2007, 03:16
 
Fecha de Ingreso: enero-2006
Ubicación: Torroles (Costa der Só)
Mensajes: 1.017
Antigüedad: 18 años, 10 meses
Puntos: 7
Re: Un módulo de usuarios

Bravo, U_G !!! Me gusta mucho tu iniciativa. Igual me hago yo un cursillo de XML

Yo haria otra tabla para controlar los accesos de los usuarios:

Código:
tbl_accesos
--------------
session_id -------------------- String(128)
usuario_id -------------------- Long(12)
usuario_ip -------------------- String(15)
datetime_entrada ---------- DateTime
datetime_salida ------------- DateTime
Y añadiria un campo más a la tabla de usuarios:

bloqueado -------------------- Boolean

Nos permitiria banear temporalmente a determinados usuarios



Un saludo
__________________
"Tus pecados son el estiércol sobre el que florecerán las flores de tus virtudes" - Gerald Messadié -
  #3 (permalink)  
Antiguo 29/09/2007, 08:22
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 10 meses
Puntos: 98
Re: Un módulo de usuarios

Cita:
Iniciado por tammander Ver Mensaje
Bravo, U_G !!! Me gusta mucho tu iniciativa. Igual me hago yo un cursillo de XML

Yo haria otra tabla para controlar los accesos de los usuarios:

Código:
tbl_accesos
--------------
session_id -------------------- String(128)
usuario_id -------------------- Long(12)
usuario_ip -------------------- String(15)
datetime_entrada ---------- DateTime
datetime_salida ------------- DateTime
Y añadiria un campo más a la tabla de usuarios:

bloqueado -------------------- Boolean

Nos permitiria banear temporalmente a determinados usuarios



Un saludo

Gracias tamm, si, te adelantaste un poquito , la idea es mas o menos hacer bien básico un ABM pero ir incorporando funcionalidades, para demostrar que a veces si puedes hacer "future proof" de un sistema, en un rato más detallaremos el formulario y sí, estaría genial si nos regalas un curso de XML

Saludos my friend
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #4 (permalink)  
Antiguo 29/09/2007, 09:39
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 10 meses
Puntos: 98
Re: Un módulo de usuarios

Antes que nada les comento que trataré castellanizar en la medidad de lo posible la aplicación salvo en casos que son tan comunes que se hagan en inglés que hasta suena raro hacer algún tipo de traducción, lo cuál también es una práctica muy difícil para mí ya que entiendo el spanglish fluídamente y lo escribo exclusivamente bueno, vamos a trabajar, lo que haremos hoy será:

- Crear la estructura inicial de archivos dentro de nuestro folder "admin"
- Trazar el HTML del formulario de login
- Hablar un poco acerca de la clase usuario

Vamos a colocarnos en: Raiz del Sitio\Admin\

* Crea los siguientes archivos, dejalos todos en blanco:
  • footer.asp
  • header.asp
  • login.asp
  • estilos.css
  • libreria.js

Más o menos así debe haber quedado tu folder:
admin1.gif


* Acerca de los archivos header.asp y footer.asp
Por cuestiones de reutilización de código siempre es recomendable hacer un archivo header(encabezado, ya lo sabías ¿cierto?) y footer, los cuales estarán en la parte de arriba y abajo de tu aplicación, en esta ocasión estamos trabajando en el "backend" por lo cuál estos archivos residen dentro de la carpeta admin.

Regularmente la estructura básica del HTML debería estar en otro archivo y llamar a nivel de include a aquellos archivos que dan contenido, esto se hace más que nada en el front end, pues es dónde regularmente requires un poco de más dinamismo, en tanto que el backend puede llegar a ser un poco más constante en cuanto a su conducta se refiere, la idea es la siguiente:

Código:
<html>
   <!--#include file = "header.asp"-->
   <%
        'Serie de condiciones que pone al archivo en vistas distintas por medio de llamadas include a diferentes  archivos.
    %>
   <!--#include file = "footer.asp"-->
</html>
Obviamente en el header tendríamos nuestra definicón del tag head y todo lo que conlleva y el inicio del tag body, en el footer pues tendremos la parte de abajo del website, el footer de FDW podría comenzar donde se lee: "Todas las horas son GMT -7. La hora es 07:36:15."

No estoy aquí para enseñarte HTML, ya que estoy seguro que para este momento serás un experto, sin embargo, nunca está de más hacer un repaso rápido, así que brevemente detallaremos el HTML de nuestro formulario de login:

Abre tu archivo header.asp, y pega por favor el siguiente código:
Código:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <link rel="stylesheet" href="estilos.css" type="text/css" media="all" />
        <meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
        <script type="text/javascript" src="libreria.js"></script>
    </head>
    <body>
Por favor, no nos acostumbremos a hacernos alérgicos al tipo de documento, siempre es una buena costumbre incluírlo, mas info aquí.
Dentro de la etiqueta header estoy poniendo nuestra hoja de estilos, un archivo javascript y el charset, este último es bien importante, y espero me perdones por no incluír titulo, descripción y demás, pero tú si lo puedes hacer bien en tu aplicación

Continuaremos en nuestro archivo footer.asp, por favor, abre copia y pega el siguiente HTML:

Código:
    </body>
</html>
Bueno, ya tenemos nuestro esqueleto HTML, ahora si, podemos ponernos a trabajar con nuestro formulario de login:

Código:
<form action="login.asp" method="post" id="formaAsp">
    <input type="hidden" name="formaEnviada" value="1" />
    <input type="hidden" name="accion" value="ingresar" />
    
    <fieldset class="forma">
        <legend>Introduzca sus datos de acceso</legend>
        <div class="formaEtiqueta">
            <label for="uname">Usuario:&nbsp;</label>
        </div>
        <div class="formaCampo">
            <input type="text" id="uname" name="uname" value="" maxlength="50" />
        </div>
        <br />
        <div class="formaEtiqueta">
            <label for="pwd">Password:&nbsp;</label>
        </div>
        <div class="formaCampo">
            <input type="password" id="pwd" name="pwd" maxlength="8" vcalue="" />
        </div>
        <br />
        <input type="submit" value="Ingresar" class="formaBoton" />
    </fieldset>
</form>
Como te dije anteriormente, no pretendo re-enseñarte HTML, pero revisaremos rápidamente la estructura de nuestro formulario.

<form action="login.asp" method="post" id="formaAsp">

Esta forma viaja al archivo login.asp, es decir que se llamará a si misma.
Viaja por post, es decir que entre otras cosas los valores no se muestran en la URL
El identiicador único de esta forma es formaAsp, todo elemento HTML debería en teoría tener un identificador único mediante el cuál poder hacer referencia.

Por lo demás, desde hace ya algunos años la tendencia es no maquetar con tablas, sino hacerlo con css, para los que venimos de la vieja escuela de tablas fué todo un reto pensar en contendores en lugar de celdas y posicionamientos en lugar de spacing y padding, pero una vez que lo conseguimos, no nos queda otra que presumirlo

Basicamente utilizamos un "wrapper" para los elementos label e input que haremos flotantes y utilizamos el <br /> para hacer un "clearing" entre lineas de elementos, pero nos dedicaremos mas adelante a dejarlo bonito.

Por lo demás por costumbre del lugar donde actualmente trabajo, tenemos que hacer aplicaciones que en la medida de lo posible cumplan con la famosa sección 508 la cual se refiere a crear aplicaciones en las cuales las personas con ciertas discapacidades puedan acceder a la información, aquí en nuestro foro hay mucha info al respecto , la parte destacable entonces, es esta:

Código:
<label for="uname">Usuario:&nbsp;</label>
<input type="text" id="uname" name="uname" value="" maxlength="50" />
Básicamente lo que se hace es asociar mediante el atributo "for" del elemento label, a la etiqueta del formulario con su campo correspondiente, de esta manera si una persona es invidente y está utilizando un lector de HTML, podrá llenar el formulario al saber que lo que contenga la etiqueta label es el texto para el campo que tiene un id uname, en este caso, el nombre de usuario.

Por último, abre el archivo login.asp y coloca todo el código:

Código:
<!--#include file = "../admin/header.asp"-->
<form action="login.asp" method="post" id="formaAsp">
    <input type="hidden" name="formaEnviada" value="1" />
    <input type="hidden" name="accion" value="ingresar" />
    
    <fieldset class="forma">
        <legend>Introduzca sus datos de acceso</legend>
        <div class="formaEtiqueta">
            <label for="uname">Usuario:&nbsp;</label>
        </div>
        <div class="formaCampo">
            <input type="text" id="uname" name="uname" value="" maxlength="50" />
        </div>
        <br />
        <div class="formaEtiqueta">
            <label for="pwd">Password:&nbsp;</label>
        </div>
        <div class="formaCampo">
            <input type="password" id="pwd" name="pwd" maxlength="8" vcalue="" />
        </div>
        <br />
        <input type="submit" value="Ingresar" class="formaBoton" />
    </fieldset>
</form>
<!--#include file = "../admin/footer.asp"-->
¿Qué crees? que ya me extendí demasiado por hoy, y tengo que cortar aquí, revisaremos la clase usuario en la próxima ocasión.

Saludos!
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway

Última edición por Myakire; 30/09/2007 a las 09:20 Razón: Cambiar unas etiquetas dado el copy-paste estaban incorrectas
  #5 (permalink)  
Antiguo 29/09/2007, 10:30
Avatar de Shiryu_Libra
Colaborador
 
Fecha de Ingreso: febrero-2007
Ubicación: Cantando "Screenager" en "Kirafa Kaput"
Mensajes: 3.614
Antigüedad: 17 años, 8 meses
Puntos: 88
Re: Un módulo de usuarios

muy buena clase "Master of Darkness" U_G(), refrescar un poco la memoria y compartilo con nosotros
mas de 1 te lo agradecera

solo por remembranza de un post anterior

"evitar que los campos contenga palabras reservadas de ACCESS, SQL y los simbolos (_, -, *, /, y similares )" para evitar errores de consulta, en el caso que nuestro gran "Ticher" propuso se escriben entre corchetes [usuario_id].

__________________
"Eres parte del problema, parte de la solucion o parte del paisaje"
Un Saludo desde Desierto de Altar, Sonora, MX.
Shiryu_libra

Última edición por Shiryu_Libra; 29/09/2007 a las 10:50
  #6 (permalink)  
Antiguo 30/09/2007, 09:50
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 10 meses
Puntos: 98
Re: Un módulo de usuarios

Cita:
para evitar errores de consulta, en el caso que nuestro gran "Ticher" propuso se escriben entre corchetes [usuario_id].
Hola, intentaré en este post diario antes de entrar en materia contestar a sus comentarios, sugerencias y dudas si hubiera alguna, gracias al caballero del zodiaco por su observación, sin embargo el guion bajo es muy usado en el ambiente de bases de datos, realmente me sorprenderia si tuvieras que ocupar los corchetes, realmente nunca me ha sucedido aunque no diga que no puede ser posible, si creo que la posibilidad es remota.

Ahora si, a trabajar.
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #7 (permalink)  
Antiguo 30/09/2007, 10:03
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 10 meses
Puntos: 98
Re: Un módulo de usuarios

Para comenzar, se me olvidó el día de ayer revisar un par de campos hidden que se encuentran en nuestro formulario, con frecuencia en el desarrollo web, cuando trabajamos con formularios tenemos que envíar datos que no siempre queremos que el usuario a simple vista detecte, pero que por alguna razón nuestro sistema necesita conocer, para este propósito nos valemos de los campos de tipo "hidden" u escondidos/ocultos, para los que comienzan o planean comenzar con .NET, los campso hidden son representados por el objeto ViewState, -solo queria destacar esto porque a mi me costo mucho trabajo averiguarlo - si observamos nuestro formulario de login, tenemos 2:

Código:
    <input type="hidden" name="formaEnviada" value="1" />
    <input type="hidden" name="accion" value="ingresar" />
Como mencioné el día de ayer, esta forma hará que el archivo login.asp se llame a si mismo, de manera tal que tenemos que tener algo que le diga a nuestro archivo que hacer en qué momento, para esto ocuparemos el primer hidden, que básicamente le dirá a nuestro archivo que la forma de login ha sido envíada, de ahí su nombre "formaEnviada".

Con respecto al 2do campo, estaba pensando que sería bueno en caso de querer reutilizar este formulario, pero ahora no se que tan buena idea, sea, así que no le demos importancia y dejémoslo ahí mientras, aunque si eres perfeccionista ya se que me vas a gritar que ese campo lo único que hace es utilizar ancho de banda necesariamente, pero qué diablos, yo nunca he pagado por ancho de banda

Ahora que hemos terminado de revisar el detalle del HTML, pasemos al parte lógica, para eso me gustaría continuar en otro post...
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #8 (permalink)  
Antiguo 30/09/2007, 11:41
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 10 meses
Puntos: 98
Re: Un módulo de usuarios

* Un vistazo breve al interior de una clase

Hay muchísimo de que hablar sobre este tema, no pretendo ni con mucho adentrarme y en realidad no se hasta que punto podría hacerlo eficientemente, así que solo repasaremos rápida y condensadamente los puntos básicos que debemos saber antes de aventurarnos a escribir nuestra clase usuario.

Técnicamente hablando, una clase es un conjunto de propiedaes, métodos y eventos* que interactúan entre sí que da como resultado un plano o blueprint de algún objeto, es decir, nosotros diseñamos las clases para que al instanciarlas se conviertan en objetos. Un objeto es una instancia de alguna clase, un objeto entonces tiene propiedades, métodos y eventos.

- Propiedad: La definición rápida y contundente es: Una cualidad de los objetos, una propiedad del objeto automóvil podría ser su color.
- Método: Acción que realiza el objeto, un automóvil, acelera.
- Eventos: Es algo que ocurre que dispara un método, pisar el acelerador ocasiona que el automóvil acelere.

Nuestra clase usuario tendrá para comenzar 3 propiedades, las cuales podemos encontrar en nuestra tabla tbl_usuario, aunque no siempre una propiedad refleja un campo en la base de datos.

A las propiedades se les puede asignar un valor, pero también podemos rescatar su valor, no siempre una propiedad puede ser establecida y rescatada, pero para efectos de nuestro ejercicio así será.

La sintáxis para referirnos a las propiedades de nuestros objetos en VBS es la siguiente:

Código:
'Asignar valor
Objeto.propiedad = valor

'Rescatar valor
valor = Objeto.propiedad
Ahora para efectos de nuestra clase, necesitamos dos miembros por cada propiedad, un miembro público y otro privado, un miembro público es aquél que es visto desde afuera del objeto, los dos ejemplos anteriores se refieren a un miembro público de nuestro objeto, por ende, necesitamos valernos de dos métodos, uno para asignar el valor, otro para devolverlo.

Código:
'Miembro privado que se llama id
private m_id

'Asigna el valor
public property let id(p_data)
  m_id = p_data
end property

'Devuelve el valor
public property get id()
    id = m_id
end property
La sintaxis para comenzar a diseñar una clase es la siguiente:
Código:
Class usuario
    .
    .
    .
End Class
La sintaxis para instanciar una clase o crear un objeto es la siguiente:
Código:
'Dimensionamos nuestra variable que se convertira en el objeto
Dim Objusuario

'Instanciamos nuestro objeto
Set Objusuario = new usuario
'ejecutamos las operaciones deseadas con nuestro objeto

'Es una buena costumbre destruir nuestros objetos
Set ObjUsuario = Nothing
Ok, ya estamos listos para comenzar a codificar nuestra clase

En el folder componentes, crea el archivo: usuario.asp y codifiquemos el siguiente código que nos permitirá poder acceder a los propiedades básicas de nuestra clase usuario -ya iremos agregando mas cosas-

Código:
<%
Class usuario
    private m_id
    private m_uname
    private m_pwd
    
    public property get id()
        id = m_id
    end property
    public property let id(p_data)
        m_id = p_data
    end property
    
    public property get uname()
        uname = m_uname
    end property
    public property let uname(p_data)
        m_uname = p_data
    end property
    
    public property get pwd
        pwd = m_pwd
    end property
    public property let pwd(p_data)
        m_pwd = p_data
    end property


End Class
%>

'Ok, ya podemos probar nuestra clase

<!--#include file = "componentes/usuario.asp"-->
<%
Dim ObjUsuario
Set ObjUsuario = new usuario

'Asignamos un valor
ObjUsuario.uname = "Este es mi nombre"

'Lo recuperamos
Response.Write(ObjUsuario.uname)

Set ObjUsuario = Nothing
%>
En la próxima ocasión comenzaremos a agregar un poco de lógica a nuestro formulario.

Saludos
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #9 (permalink)  
Antiguo 30/09/2007, 21:54
Avatar de a83
a83
 
Fecha de Ingreso: noviembre-2005
Ubicación: Santiago de chile
Mensajes: 637
Antigüedad: 19 años
Puntos: 1
Re: Un módulo de usuarios

nada que decir exelente :)
  #10 (permalink)  
Antiguo 01/10/2007, 10:09
Avatar de JuanRAPerez
Colaborador
 
Fecha de Ingreso: octubre-2003
Mensajes: 2.393
Antigüedad: 21 años, 1 mes
Puntos: 27
Re: Un módulo de usuarios

excelente.

gracias de mi parte pot este post
__________________
JuanRa Pérez
San Salvador, El Salvador
  #11 (permalink)  
Antiguo 01/10/2007, 10:44
Avatar de AlZuwaga
Colaborador
 
Fecha de Ingreso: febrero-2001
Ubicación: 34.517 S, 58.500 O
Mensajes: 14.550
Antigüedad: 23 años, 9 meses
Puntos: 535
Re: Un módulo de usuarios

Ansioso espero el capítulo del lunes!

:aplausos:
__________________
...___...
  #12 (permalink)  
Antiguo 01/10/2007, 13:31
Avatar de Myakire
Colaborador
 
Fecha de Ingreso: enero-2002
Ubicación: Centro de la república
Mensajes: 8.849
Antigüedad: 22 años, 10 meses
Puntos: 146
Re: Un módulo de usuarios

Oiga maestro, ¿que pasaría si yo no asigno un valor a la propiedad uname y de todas formas la despliego? ¿no debería tener un valor por default?

El alumno que se adelanta para llamar la atención nunca falta
  #13 (permalink)  
Antiguo 01/10/2007, 13:51
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 10 meses
Puntos: 98
Re: Un módulo de usuarios

Cita:
Iniciado por Myakire Ver Mensaje
Oiga maestro, ¿que pasaría si yo no asigno un valor a la propiedad uname y de todas formas la despliego? ¿no debería tener un valor por default?

El alumno que se adelanta para llamar la atención nunca falta
Te voy a dar este citatorio para tus padres, traelo firmado por ellos mañana por la mañana o te regreso a tu casa

En un rato más nos ponemos a agregar lógica a nuestro form.

Saludos
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #14 (permalink)  
Antiguo 01/10/2007, 15:11
Avatar de Epunamun  
Fecha de Ingreso: noviembre-2004
Mensajes: 133
Antigüedad: 20 años
Puntos: 0
Re: Un módulo de usuarios

nunca habia leido un manual realmente bueno no te puedo decir mas uqe felicitaciones
  #15 (permalink)  
Antiguo 01/10/2007, 18:19
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 10 meses
Puntos: 98
Re: Un módulo de usuarios

Primero que nada ¡Gracias por sus comentarios!

Ahora que comencé a probar un poco la aplicación me encontré con un par de errores que solo me muestra que nadie ha seguido el código

Fé de erratas:
* Global.asa, línea 5, por favor renombrar la variable a:
Código:
Application("baseDatosRutaServidor")
'tenia una 'o' entre Ruta y Servidor

* Conexion.asp, línea 5, cambiar la variable anterior y agregar la variable que contiene el nombre de la base de datos:
Código:
strConnect = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="&Application("baseDatosRutaServidor")&Application("baseDatosNombre")&";"
Ahora si, a trabajar...
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #16 (permalink)  
Antiguo 01/10/2007, 19:38
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 10 meses
Puntos: 98
Re: Un módulo de usuarios

En Programación Orientada a Objetos (OOP ó POO), generalmente tenemos dos métodos que se llaman "Constructor y Destructor" para cada clase, éstos son ejecutados cada vez que la clase se instancia o se destruye respectivamente, VBS al no ser un lenguaje OOP, no tiene tales métodos, sin embargo, implementa dos subrutinas similares llamadas

Class_Initialize y Class_Terminate respectivamente, sendas subrutinas se ejecutan al iniciar y destruir nuestro objeto, como son privadas, solo se ven en el interior de nuestra clase, es decir, no podremos hacer que nuestro objeto llame a estos métodos a voluntad, el sabe que los ejecutará al iniciar y terminar, si no se definen estos métodos, no pasa nada, en caso que te estuvieras preguntando .

Ahora, Myakire se adelantó hace rato por eso le dí un citatorio para sus papás (no tanto) realmente no tenía planeado incluír este método pero ya que metió su cuchara tendremos que hacerlo (gracias )

Vamos a trabajar y hagamos que al instanciar nuestra clase, sus propiedades tomen valores por defecto, abrimos nuestro archivo usuario.asp y escribimos nuestra subrutina Class_Initialize:

Código:
	Private sub Class_Initialize
		m_id = -1
		m_uname = ""
		m_pwd = ""
	End sub
Esto hará el truco


* Lógica del formulario
Es siempre la mejor idea sentarse un rato a pensar antes de comenzar a tirar líneas de código, te sugiero siempre crear un algoritmo básico para todo proceso, y siempre tratar de hacerlo de manera ordenada y estandarizada, programar una aplicación ordenadamente te ahorrará muchos dolores de cabeza a tí y a quien mantenga tu sistema -y dirán uy si que ordenado es u_g, para nada, pero trato de serlo aunque nunca lo logro- en fin, básicamente de lo que se trata la lógica de nuestro archivo es:

- Detectar si la forma ha sido envíada cuando la página carga
- Si ha sido envíada tratará de "loguear" al usuario
- Si el usuario es autentificado, ya ganamos
- Si el usuario no es autentificado, redireccionaremos a nuestra misma forma, y le avisaremos que una de dos, o las dos (usuario y password) no son válidos.

¿Fácil no?

Abrimos nuestro archivo admin/login.asp, y comenzamos después de la serie de includes, vamos a tratar a lo largo de todo este módulo de declarar todas las variables que utilizaremos, no solo es una buena costumbre, sino ayudará para que ahora que migremos a otros lenguajes, no nos cueste trabajo deshacernos de la herencia maldita de VB:

Código:
<%
'una variable booleana que nos ayudará para saber si la forma se ha envíado
Dim formaHasidoEnviada
'Nuestro objeto usuario
Dim ObjUsuario
'Si existe un error lo imprimiremos con esta varibale
Dim strError

'Si el campo formaEnviada que es nuestro hidden tiene un valor, quiere decir que la forma se ha enviado
formaHasidoEnviada = len(Request.Form("formaEnviada")) > 0
'Inicializamos nuestro variable de error a nada por el momento
strError = ""

'Continua...
Ahora viene la parte divertida...vamos a ver que mostramos de acuerdo a nuestras variables:

Código:
'Si no se ha enviado la forma
if not formaHasidoEnviada then
	'Si existe algun error guardado en sesion, entonces nuestra variable de error adquirira un valor
	if Session("loginError") then
		strError = "Usuario o contraseña incorrectos, por favor intente de nuevo"
		'Si hubo error ya tenemos nuestro string, no tiene caso que sigamos cargando con una variable
		'de sesion mas, asi que la quitamos.
		Session.Contents.Remove("loginError")
	end if
	%>
	<!--Agregamos un div que sirva como etiqueta para mostrar el error, esto va arriba del form--->
	<div class="error"><%=strError%></div>
	<!--Aqui va nuestro formulario--->
else
	'Se ha enviado la forma, necesitamos comprobar al usuario
	'Instanciamos nuestro clase usuario, aqui se llama automaticamente a la subrutina Initialize
	Set ObjUsuario = new usuario
	'Recuperamos nuestros valores asignandolos a su propiedad correspondiente...les quitamos los strings 	'vacios al inicio y final de la cadena
	ObjUsuario.uname = trim(Request.Form("uname"))
	ObjUsuario.pwd = trim(Request.Form("pwd"))
	
	'----------Esta parte la trabajaremos mañana------
	'if ObjUsuario.Autentificar() then
	'	Response.Write("Ahora si ingresaste")
	'else
	'	Set ObjUsuario = Nothing
	'	Session("usuarioID") = ""
	'	Session("loginError") = true
	'	Response.Redirect("login.asp")
	'end if
	'--------------------------------------------------
end if
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #17 (permalink)  
Antiguo 01/10/2007, 19:42
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 10 meses
Puntos: 98
Re: Un módulo de usuarios

Falta agregar en la parte superior de nuestro archivo, los includes correspondientes de la cadena de conexión y la clase usuario, sin estos includes los Dioses del ASP, se enojarán con nosotros:

Código:
<!--#include file = "../conexion.asp"-->
<!--#include file = "../componentes/usuario.asp"-->
Al final, nuestro código quedará más o menos así:

Código:
<!--#include file = "../conexion.asp"-->
<!--#include file = "../componentes/usuario.asp"-->
<!--#include file = "../admin/header.asp"-->
<%
Dim formaHasidoEnviada
Dim ObjUsuario
Dim strError

formaHasidoEnviada = len(Request.Form("formaEnviada")) > 0
strError = ""

if not formaHasidoEnviada then
	if Session("loginError") then
		strError = "Usuario o contraseña incorrectos, por favor intente de nuevo"
		Session.Contents.Remove("loginError")
	end if
	%>
	<div class="error"><%=strError%></div>
	<form action="login.asp" method="post" id="formaAsp">
		<input type="hidden" name="formaEnviada" value="1" ID="Hidden1"/>
		<input type="hidden" name="accion" value="ingresar" ID="Hidden2"/>
	    
		<fieldset class="forma">
			<legend>Introduzca sus datos de acceso</legend>
			<div class="formaEtiqueta">
				<label for="uname">Usuario:&nbsp;</label>
			</div>
			<div class="formaCampo">
				<input type="text" id="uname" name="uname" value="" maxlength="50" />
			</div>
			<br />
			<div class="formaEtiqueta">
				<label for="pwd">Password:&nbsp;</label>
			</div>
			<div class="formaCampo">
				<input type="password" id="pwd" name="pwd" maxlength="8" vcalue="" />
			</div>
			<br />
			<input type="submit" value="Ingresar" class="formaBoton" />
		</fieldset>
	</form>
<%
else
	Set ObjUsuario = new usuario
	ObjUsuario.uname = trim(Request.Form("uname"))
	ObjUsuario.pwd = trim(Request.Form("pwd"))
	
	'----------Esta parte la trabajaremos mañana------
	'if ObjUsuario.Autentificar() then
	'	Response.Write("Ahora si ingresaste")
	'else
	'	Set ObjUsuario = Nothing
	'	Session("usuarioID") = ""
	'	Session("loginError") = true
	'	Response.Redirect("login.asp")
	'end if
	'--------------------------------------------------
end if
%>
<!--#include file = "../admin/footer.asp"-->
Mañana implementaremos el método de autentificar y hablaremos del objeto Command, al final del día tendremos nuestro form funcionando .


Saludos
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #18 (permalink)  
Antiguo 02/10/2007, 07:13
Avatar de Myakire
Colaborador
 
Fecha de Ingreso: enero-2002
Ubicación: Centro de la república
Mensajes: 8.849
Antigüedad: 22 años, 10 meses
Puntos: 146
Re: Un módulo de usuarios

Para que no digas que nadie sigue el código :

<input type="password" id="pwd" name="pwd" maxlength="8" vcalue="" />


Mis padres no pudieron venir, pero mi padre se aventó una firma sobre el citatorio espero que con eso ya pueda volver a entrar a tan interesante clase
  #19 (permalink)  
Antiguo 02/10/2007, 23:28
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 10 meses
Puntos: 98
Re: Un módulo de usuarios

Cita:
Iniciado por Myakire Ver Mensaje
Para que no digas que nadie sigue el código :

<input type="password" id="pwd" name="pwd" maxlength="8" vcalue="" />


Mis padres no pudieron venir, pero mi padre se aventó una firma sobre el citatorio espero que con eso ya pueda volver a entrar a tan interesante clase
Gracias con respecto a "la firma de tu padre", esteeeeeeeeee, mejor ni hablar :-p

Bueno chic@s, nos quedamos en que necesitabamos implementar nuestro primer método público de la clase usuario que nos servirá para autentificar a nuestro usuario.

Primero que nada, dos recomendaciones importantes con respecto al acceso a datos:

1. No dejen campos nulos en sus tablas si no es algo que realmente se necesite, los datos nulos ralentizan las consultas y le dan a la aplicación una tarea extra que hacer -manejar otro tipo de dato-, en la medida de lo posible, utiliza valores por defecto para tus campos, estandarízalos de modo que tu aplicación los entienda, por ejemplo, yo se que en mis aplicaciones la fecha '1/1/1800' es regularmente un valor por defecto salvo en los casos que estemos tratando de fechas históricas, así pues, vamos a poner valores por defecto a nuestros campos:

usuario_uname | ''
usuario_pwd | ''

2. Parametricen sus consultas, es una buena práctica que ayuda a tener un orden, saber precisamente el tipo de dato, su longitud, por si fuera poco, ayuda a controlar la inyección de SQL, esta es una lectura que siempre recomiendo, creo recordar que existia el mismo artículo en español, pero no encontré el link

Nuestra forma tradicional de hacer consultas SQL, es un string, al cual concatenamos variables, dicho en nuestro idioma:

Código:
Ej. 1
uname = Request("valor")
pwd = Request("valor")
query = "SELECT usuario_id FROM tbl_usuario WHERE usuario_uname = '" & uname & "' AND pwd = '" & pwd & "'"
Está perfecto ¿no es así? el query se forma correctamente y la sintáxis es correcta, ahora qué pasa si envío los siguientes valores?

usuario
' OR 1 = 1

pwd
' OR 'A' = 'A

Sutituimos los valores:
Código:
SELECT usuario_id FROM tbl_usuario WHERE usuario_uname = '' OR 1 = 1 AND pwd = '' OR 'A' = 'A'
A mi me parece una sentencia correcta y que además siempre será verdadera ¿A tí?

La solución es controlar la comilla simple, pero ¿Qué pasa en el caso de valores numéricos? Supóngase el caso de una página de detalles donde envíamos el id por querystring:

Código:
SELECT campos FROM tabla WHERE campoid = Request.QueryString("id")
Recuerden que para hacer un ataque, se require un poco de intuición, así que supongamos que mediante ciertas excepciones provocadas, nuestro atacante se entera de que tenemos un campo llamado user_uname y nos envía por querystring lo siguiente:

id=1+update tbl_usuario set usuario_uname='<script type=text/javascript>location.href=http://www.unsitio.com</script>'

NUestra consulta quedaría de la siguiente forma:
Código:
SELECT campos FROM tabla WHERE campoid = 1+update tbl_usuario set usuario_uname='<script type=text/javascript>location.href=http://www.unsitio.com</script>'
Woops, que crees? también es una consulta válida, que no solo nos hace una inyección de sql, sino también nos inyectan javascript.

Recuerda que ninguna técnica debe tomarse como religión, quizás te puedas valer de ciertas funciones para reemplazar los posibles ataques de este tipo, pero en todo este tiempo que he estado trabajando con ASP, no he encontrado nada más ordenado, simple y concreto que el objeto command como medio de seguridad.

*El objeto Command desmistificado:

Te voy a poner la parte condensada sin tantos rodeos, básicamente se trata de hacer nuestra consulta, y en lugar de concatenar variables de VBS, envíamos a la consulta un caractér que nuestro objeto reconoce como un parámetro, y se representa mediante un signo de interrogación (?), cada parámetro necesita tener un:

nombre, tipo de dato, tipo de parámetro, tamaño y valor


¿Qué datos requiere el objeto command?
- Conexión activa
- Tipo de Comando
- Texto del comando, la consulta
- Parámetros


-Tipos de datos más comunes para parámetros y su tamaño

adInteger | 4
adDouble | 8
adDate | 8
adVarChar | tamaño del campo
adBoolean | 1
adLongVarChar | regularmente mas de 1000,000

Aterrizando todo:

Código:
Dim ObjConn
Dim rs
Dim cmd
Dim param
Dim qry
Dim id

id = Request.QueryString("id")

'Comando
Set cmd = Server.CreateObject("ADODB.Command")
Set rs = Server.CreateObject("ADODB.Recordset")
Set ObjConn = Server.CreateObject("ADODB.Connection")

'CommandText
qry = "SELECT campo FROM tabla WHERE campoid = ?"

'Parámetro en orden, solo tenemos uno, el id
Set param = cmd.CreateParameter("id", adInteger, adParamInput, 4, id)
cmd.Parameters.Append(param)


ObjConn.Open strConnect
'Conexion activa
cmd.ActiveConnection = ObjConn
'Tipo de comando
cmd.CommandType = adCmdText
'command text para el comando
cmd.CommandText = qry

'abrimos nuestro recordset
rs.Open cmd
Y eso sería todo...qué crees? que me extendí mucho y no me da más tiempo de implementar el método, así que lo dejaremos para el rato


Saludos
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #20 (permalink)  
Antiguo 03/10/2007, 08:53
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 10 meses
Puntos: 98
Re: Un módulo de usuarios

Ya que tenemos la teoría, pasemos a la práctica, si se fijan en nuestro formulario, comentamos la parte donde el usuario se autentifica:

Código:
	'if ObjUsuario.Autentificar() then
	'	Response.Write("Ahora si ingresaste")
	'else
	'	Set ObjUsuario = Nothing
	'	Session("usuarioID") = ""
	'	Session("loginError") = true
	'	Response.Redirect("login.asp")
	'end if
Como ya vimos, esto se refiere a un método público de la clase usuario llamado Autenficar, que congruente con su aplicación, regresa un boolean si/no el usuario tiene suficientes credenciales, vamos pues a trabajar en nuestro método, abrimos el archivo componentes\usuario.asp y comenzamos a codificar nuestro método Autentificar:

Código:
Public function Autentificar()
        Dim ObjConn
        Dim rs
        Dim cmd
        Dim param
        Dim esUnaAccionExitosa
        Dim qry
        
        esUnaAccionExitosa = false
        
        Set ObjConn = Server.CreateObject("ADODB.Connection")
        Set rs = Server.CreateObject("ADODB.Recordset")
        Set cmd = Server.CreateObject("ADODB.Command")
        
        qry = "SELECT usuario_id FROM tbl_usuario WHERE usuario_uname = ? AND usuario_pwd = ?"
        
        Set param = cmd.CreateParameter("uname", adVarChar, adParamInput, 50, m_uname)
        cmd.Parameters.Append(param)
        Set param = cmd.CreateParameter("pwd", adVarChar, adParamInput, 50, m_pwd)
        cmd.Parameters.Append(param)
        
        ObjConn.Open strConnect
        cmd.ActiveConnection = ObjConn
        cmd.CommandType = adCmdText
        cmd.CommandText = qry
        
        rs.Open cmd
        
        if not rs.EOF then
            m_id = rs("usuario_id")
            esUnaAccionExitosa = true
        else
            m_id = -1
            esUnaAccionExitosa = false
        end if
        
        Set ObjConn = Nothing
        Set rs = Nothing
        Set cmd = Nothing
        Set param = Nothing
        
        Autentificar = esUnaAccionExitosa
end function
Como podrás ver, no tiene ninguna ciencia, simplemente debemos pasarle valores para las propiedades uname y pwd, el método se encarga de hacer una consulta parametrizada a la base de datos, si el usuairo ha sido autentificado, la propiedad id, adquirirá el valor del id del usuario, y el regresará verdadero, si no, regresará falso. Otra cosa mas que destacar es como usamos el string de conexion contenido en conexion.asp que se convierte en una variable super global, los que no estén de acuerdo y estén a punto de gritarme que una clase no debe depender de un valor externo y demás, podrían mover su string de conexión al global.asa por ejemplo, e inicializar su valor en el método Initialize, pero para mi, y espero que para ti también funciona bien de este modo, solo acuérdate de incluir tu archivo de conexion arriba de tus clases.

Bien, nuestro archivo usuario.asp quedaría de la siguiente manera:
Código:
<%
Class usuario
    private m_id
    private m_uname
    private m_pwd
    
    public property get id()
        id = m_id
    end property
    public property let id(p_data)
        m_id = p_data
    end property
    
    public property get uname()
        uname = m_uname
    end property
    public property let uname(p_data)
        m_uname = p_data
    end property
    
    public property get pwd
        pwd = m_pwd
    end property
    public property let pwd(p_data)
        m_pwd = p_data
    end property

    Public function Autentificar()
        Dim ObjConn
        Dim rs
        Dim cmd
        Dim param
        Dim esUnaAccionExitosa
        Dim qry
        
        esUnaAccionExitosa = false
        
        Set ObjConn = Server.CreateObject("ADODB.Connection")
        Set rs = Server.CreateObject("ADODB.Recordset")
        Set cmd = Server.CreateObject("ADODB.Command")
        
        qry = "SELECT usuario_id FROM tbl_usuario WHERE usuario_uname = ? AND usuario_pwd = ?"
        
        Set param = cmd.CreateParameter("uname", adVarChar, adParamInput, 50, m_uname)
        cmd.Parameters.Append(param)
        Set param = cmd.CreateParameter("pwd", adVarChar, adParamInput, 50, m_pwd)
        cmd.Parameters.Append(param)
        
        ObjConn.Open strConnect
        cmd.ActiveConnection = ObjConn
        cmd.CommandType = adCmdText
        cmd.CommandText = qry
        
        rs.Open cmd
        
        if not rs.EOF then
            m_id = rs("usuario_id")
            esUnaAccionExitosa = true
        else
            m_id = -1
            esUnaAccionExitosa = false
        end if
        
        Set ObjConn = Nothing
        Set rs = Nothing
        Set cmd = Nothing
        Set param = Nothing
        
        Autentificar = esUnaAccionExitosa
    End function

End Class
%>
Ahora vamos a quitarle el código comentado al archivo login.asp y detallarlo un poco más:

Código:
<!--#include file = "../conexion.asp"-->
<!--#include file = "../componentes/usuario.asp"-->
<!--#include file = "../admin/header.asp"-->
<%
Dim formaHasidoEnviada
Dim ObjUsuario
Dim strError

formaHasidoEnviada = len(Request.Form("formaEnviada")) > 0
strError = ""

if not formaHasidoEnviada then
	if Session("loginError") then
		strError = "Usuario o contraseña incorrectos, por favor intente de nuevo"
		Session.Contents.Remove("loginError")
	end if
	%>
	<div class="error"><%=strError%></div>
	<form action="login.asp" method="post" id="formaAsp">
		<input type="hidden" name="formaEnviada" value="1" />
		<input type="hidden" name="accion" value="ingresar" />
	    
		<fieldset class="forma">
			<legend>Introduzca sus datos de acceso</legend>
			<div class="formaEtiqueta">
				<label for="uname">Usuario:&nbsp;</label>
			</div>
			<div class="formaCampo">
				<input type="text" id="uname" name="uname" value="" maxlength="50" />
			</div>
			<br />
			<div class="formaEtiqueta">
				<label for="pwd">Password:&nbsp;</label>
			</div>
			<div class="formaCampo">
				<input type="password" id="pwd" name="pwd" maxlength="8" value="" />
			</div>
			<br />
			<input type="submit" value="Ingresar" class="formaBoton" />
		</fieldset>
	</form>
<%
else
	Set ObjUsuario = new usuario
	ObjUsuario.uname = trim(Request.Form("uname"))
	ObjUsuario.pwd = trim(Request.Form("pwd"))
	
	if ObjUsuario.Autentificar() then
            'Guardamos en sesion el id del usuario
                Session("usuarioID") = ObjUsuario.id
		Response.Write("Ahora si ingresaste")
	else
		Set ObjUsuario = Nothing
		Session("usuarioID") = ""
		Session("loginError") = true
		Response.Redirect("login.asp")
	end if
end if
%>
<!--#include file = "../admin/footer.asp"-->
Lo único que agregamos fué lo que se encuentra en negritas, básicamente guardamos el id del usuario en sesión, quizás podríamos guardar el objeto usuario completo, pero a mi me ha dado muy mal resultado persistir objetos en sesión, así que mejor guardamos solamente su id, y crearemos un método ObtenerDatos() que estableciendo el id del usuario, nos devuelva todo lo demás...pero eso lo haremos después

Ahora ya puedes abrir tu base de datos y agregar un usuario

uname = usuario
pwd = 123456 'Nuestro pwd super seguro, tambien nos encargaremos de esto mas adelante


Y probamos la aplicación, espero que te funcione, si no, puedes regresar a gritarme...yo no la he probado aún
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #21 (permalink)  
Antiguo 04/10/2007, 07:55
Avatar de Myakire
Colaborador
 
Fecha de Ingreso: enero-2002
Ubicación: Centro de la república
Mensajes: 8.849
Antigüedad: 22 años, 10 meses
Puntos: 146
Re: Un módulo de usuarios

¿Cómo? ¿Eso es to, Eso es to, Eso es to-to-todo amigos?
  #22 (permalink)  
Antiguo 04/10/2007, 09:24
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 10 meses
Puntos: 98
Re: Un módulo de usuarios

No, por supuesto que no, hasta el momento solo tenemos una forma de login, pero vamos a trabajar completando los datos del usuario, aumentando el nivel de seguridad y creando metodos y formas para tener nuestro ABM

El unico problema es que anoche apague la PC con un botonazo, y hoy en la manana, no quiso arrancar, asi que estoy arrancando con un CD de Ubuntu, y ahora tratare de arreglas mi Win2003, cuando lo tenga listo continuaremos

Salud-
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #23 (permalink)  
Antiguo 04/10/2007, 22:02
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 10 meses
Puntos: 98
Re: Un módulo de usuarios

Hola a tod@s, perdonen si en esta ocasion escribo sin acentos pero es que aun no he podido reestablecer mi windows y sigo trabajando con la version "buteable" de Ubuntu, pero bueno...mientras tanto ya tenemos la forma que autentifica al usuario, pero en realidad nuestra clase usuario esta incompleta pues, nuestros usuarios no tienen nombre, apellido, ni se sabe nada de ellos, asi que retomamos nuestra clase y como mencionamos anteriormente, con frecuencia aunque no necesariamente es una regla, las propiedades de nuestras clases, representan campos en nuestra base de datos, agreguemos primero los campos a nuestra tabla de usuarios, y acto seguido las propiedades a nuestra clase...

tbl_usuario
--------------------
usuario_id | autoincremental, llave primaria
usuario_nombre | texto/varchar(50)
usuario_apellido | texto/varchar(50)

usuario_uname | texto/varchar(50)
usuario_pwd | texto/varchar(50)
usuario_activo | bit/boolean
usuario_fecha_edicion | datetime/fecha


En negritas se encuentran los nuevos campos y como comentamos, cada uno de estos campos representa una propiedad nueva en nuestra clase usuario, y como ya mencionamos, cada propiedad para efectos de nuestro ejercicio tendra 2 miembros, uno publico y otro privado y el publico, tendra dos metodos, uno que asigna valor, el otro que lo devuelve, al final de teclear todo esto, si no puedo tener exito como desarrollador, por lo menos se que de capturista si encuentro trabajo :

Nota las convenciones que estamos usando, un miembro privado lo identificaremos pues comienza con "m_" (miembro), en tanto que el publico es el mismo nombre del privado sin el "m_", y en el metodo que hacemos la asignacion, recibimos un argumento p_data que es el dato publico, ahora si, a trabajar:

Código:
private m_nombre
private m_apellido
private m_activo
private m_fecha_edicion

public property get nombre()
	nombre = m_nombre
end property
public property let nombre(p_data)
	m_nombre = p_data
end property

public property get apellido()
	apellido = m_apellido
end property
public property let apellido(p_data)
	m_apellido = p_data
end property

public property get activo()
	activo = m_activo
end property
public property let activo(p_data)
	m_activo = p_data
end property

public property get fecha_edicion()
	fecha_edicion = m_fecha_edicion
end property
public property let fecha_edicion(p_data)
	m_fecha_edicion = p_data
end property
El problema de agregar propiedades, es que no nos escapamos de tener que agregarlas en cada metodo que las llame explicitamente:

Código:
	Private sub Class_Initialize
		m_id = -1
		m_uname = ""
		m_pwd = ""
            m_nombre = ""
                m_apellido = ""
                m_activo = false
                m_fecha_edicion = Cdate("1/1/1800")
	End sub
Ok, hasta aqui vamos bien, hemos terminado de agregar las propiedades que en las partes que deben ser agregadas, ahora, si recuerdas nuestro formulario, despues de ingresar exitosamente, se establece una variable de sesion y se le asigna el valor del id del usuario, esta variable de sesion combinada con un metodo ObtenerDatos() puede ser de muchisima utilidad a lo largo de nuestra aplicacion:

Código:
Public function ObtenerDatos()
    Dim ObjConn
    Dim rs
    Dim cmd
    Dim param
    Dim accionEsExitosa
    Dim qry

   Set ObjConn = Server.CreateObject("ADODB.Connection")
   Set rs = Server.CreateObject("ADODB.Recordset")
   Set cmd = Server.CreateObject("ADODB.Command")
   accionEsExitosa = false

   qry = "SELECT a.* FROM tbl_usuario a WHERE a.usuario_id = ?"

   Set param = cmd.CreateParameter("id", adInteger, adParamInput, 4, m_id)
   cmd.Parameters.Append(param)

   ObjConn.Open strConnect
   cmd.ActiveConnection = ObjConn
   cmd.CommandType = adCmdText
   cmd.CommandText = qry

   rs.Open cmd

   if not rs.EOF then
     m_id = rs("usuario_id")
     m_nombre = rs("usuario_nombre")
     m_apellido = rs("usuario_apellido")
     m_uname = rs("usuario_uname")
     m_pwd = rs("usuario_pwd")
     m_activo = rs("usuario_activo")
     m_fecha_edicion = rs("usuario_fecha_edicion")
     accionEsExitosa = true
     rs.Close()
  else
    accionEsExitosa = false
  end if
   
   ObjConn.Close()
   Set rs = Nothing
   Set ObjConn = Nothing
   Set param = Nothing
   Set cmd = Nothing
   
   ObtenerDatos = accionEsExitosa
end function
Y su implementacion, suponiendo que ya hemos autentificado a nuestro usuario:

Código:
Set ObjUsuario = new usuario
ObjUsuario.id = Session("usuarioID")
if ObjUsuario.ObtenerDatos() then
   Response.Write("Nombre: " & ObjUsuario.nombre & " " & ObjUsuario.apellido)
   'todos los demas datos que querramos imprimir
else
   Response.Write("No se encontro el usuario")
end if
Set ObjUsuario = Nothing
Mas adelante comenzaremos a darle sentido a todo esto, por el momento ya tenemos dos metodos en nuestra clase, y uno de ellos recupera todos los datos del usuario.

* Nota: Ya se que alguno de ustedes va a aparecer para gritarme "estas usando un select * en la consulta que devuelve las propiedades del usuario", se que el hacer consultas de este tipo tiene cierto "overhead", pero tampoco es un pecado mortal para este tipo de consultas que devuelven 5 o 6 campos, hay veces que es conveniente, y este es uno de los casos pues si llegamos a editar la tabla agregar/quitar campos, no tendremos tambien que modificar el query, es un pequenio pecado, pero creo que rezando dos oraciones, seremos exhonerados


Ahora si, saludos
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway

Última edición por u_goldman; 04/10/2007 a las 22:13
  #24 (permalink)  
Antiguo 06/10/2007, 18:01
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 10 meses
Puntos: 98
Re: Un módulo de usuarios

Hola de nuevo, nos quedamos en que ya tenemos el metodo que regresa todos los datos de nuestro usuario a partir del id del usuario, tambien nos quedamos en que nuestro sistema autentifica al usuario, si te fijas, ya pasamos por:

- La creacion de un formulario HTML
- Algunos estandares HTML de usabilidad
- Algunas reglas basicas del manejo de datos
- Diseno de clases en VBS
- Hacer consultas parametrizadas mediante el objeto Command de ADO
- Implementacion de propiedades y metodos en nuestras clases


Hablamos muy poco con respecto a la seguridad de nuestra base de datos, con frecuencia en nuestros desarrollos, tenemos la mala costumbre de guardar los datos de autentificacion justo como el usuario los introduce en el formulario, el hacer esto es una muy mala practica que debemos pensar dos veces, pues recordemos que con frecuencia los usuarios ingresaran el mismo pwd para uno o varios sitios a traves de Internet, el almacenar los datos de autentificacion asi como vienen crear una vulnerabilidad importante en nuestro sistema y pone en tela de juicio nuestro profesionalismo, se que me diran "pero yo solo estoy creando una aplicacion de usuarios que modifican articulos en un sitio web pequeno", por fortuna me quedo tranquilo, que nuestros bancos, no piensen de esa manera

Bueno, a lo que vamos, estuve buscando algo que nos ayudara a implementar algo de encripcion y recurri a san google para buscar concretamente el ya famoso MD5, que conste que es solo un ejemplo y tu puedes utilizar el metodo que creas correcto, finalmente ya sabes como crear una clase, asi que todo lo que este adentro de ella no importa, lo importante es el resultado. Para tales efectos, encontre este script que me fue muy util, que conste que la licencia dice que la puedo ocupar en mi codigo y como esto que estoy haciendo es codigo de mi autoria y no lo estoy dando como demo, creo que no infrinjo las reglas.

Rapidamente recordemos que el MD5 es un algoritmo de encripcion conocido como "one way hash", es decir, no deberia haber regreso una vez encriptado, le hice unas cuantas modificaciones al codigo para encapsularlo dentro de una clase que le llamo encriptar, ahora, como nadie escribe en este post, les dejo de tarea analizar que es lo que y por que he hecho esto al codigo original.

Creamos un archivo llamado encriptar.asp dentro de nuestra carpeta de componentes (bien, nuestra segunda clase ) y pegamos el codigo modificado
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #25 (permalink)  
Antiguo 06/10/2007, 18:02
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 10 meses
Puntos: 98
Re: Un módulo de usuarios

Código:
<%
Class encriptar
	' Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm,
	' as set out in the memo RFC1321.
	'
	'
	' ASP VBScript code for generating an MD5 'digest' or 'signature' of a string. The
	' MD5 algorithm is one of the industry standard methods for generating digital
	' signatures. It is generically known as a digest, digital signature, one-way
	' encryption, hash or checksum algorithm. A common use for MD5 is for password
	' encryption as it is one-way in nature, that does not mean that your passwords
	' are not free from a dictionary attack.
	'
	' This is 'free' software with the following restrictions:
	'
	' You may not redistribute this code as a 'sample' or 'demo'. However, you are free
	' to use the source code in your own code, but you may not claim that you created
	' the sample code. It is expressly forbidden to sell or profit from this source code
	' other than by the knowledge gained or the enhanced value added by your own code.
	'
	' Use of this software is also done so at your own risk. The code is supplied as
	' is without warranty or guarantee of any kind.
	'
	' Should you wish to commission some derivative work based on this code provided
	' here, or any consultancy work, please do not hesitate to contact us.
	'
	' Web Site:  http://www.frez.co.uk
	' E-mail:    [email protected]

	private BITS_TO_A_BYTE
	private BYTES_TO_A_WORD
	private BITS_TO_A_WORD
	Private m_lOnBits(30)
	Private m_l2Power(30)

	private sub class_Initialize()

		BITS_TO_A_BYTE = 8
		BYTES_TO_A_WORD = 4
		BITS_TO_A_WORD = 32
		m_lOnBits(0) = CLng(1)
		m_lOnBits(1) = CLng(3)
		m_lOnBits(2) = CLng(7)
		m_lOnBits(3) = CLng(15)
		m_lOnBits(4) = CLng(31)
		m_lOnBits(5) = CLng(63)
		m_lOnBits(6) = CLng(127)
		m_lOnBits(7) = CLng(255)
		m_lOnBits(8) = CLng(511)
		m_lOnBits(9) = CLng(1023)
		m_lOnBits(10) = CLng(2047)
		m_lOnBits(11) = CLng(4095)
		m_lOnBits(12) = CLng(8191)
		m_lOnBits(13) = CLng(16383)
		m_lOnBits(14) = CLng(32767)
		m_lOnBits(15) = CLng(65535)
		m_lOnBits(16) = CLng(131071)
		m_lOnBits(17) = CLng(262143)
		m_lOnBits(18) = CLng(524287)
		m_lOnBits(19) = CLng(1048575)
		m_lOnBits(20) = CLng(2097151)
		m_lOnBits(21) = CLng(4194303)
		m_lOnBits(22) = CLng(8388607)
		m_lOnBits(23) = CLng(16777215)
		m_lOnBits(24) = CLng(33554431)
		m_lOnBits(25) = CLng(67108863)
		m_lOnBits(26) = CLng(134217727)
		m_lOnBits(27) = CLng(268435455)
		m_lOnBits(28) = CLng(536870911)
		m_lOnBits(29) = CLng(1073741823)
		m_lOnBits(30) = CLng(2147483647)

		m_l2Power(0) = CLng(1)
		m_l2Power(1) = CLng(2)
		m_l2Power(2) = CLng(4)
		m_l2Power(3) = CLng(8)
		m_l2Power(4) = CLng(16)
		m_l2Power(5) = CLng(32)
		m_l2Power(6) = CLng(64)
		m_l2Power(7) = CLng(128)
		m_l2Power(8) = CLng(256)
		m_l2Power(9) = CLng(512)
		m_l2Power(10) = CLng(1024)
		m_l2Power(11) = CLng(2048)
		m_l2Power(12) = CLng(4096)
		m_l2Power(13) = CLng(8192)
		m_l2Power(14) = CLng(16384)
		m_l2Power(15) = CLng(32768)
		m_l2Power(16) = CLng(65536)
		m_l2Power(17) = CLng(131072)
		m_l2Power(18) = CLng(262144)
		m_l2Power(19) = CLng(524288)
		m_l2Power(20) = CLng(1048576)
		m_l2Power(21) = CLng(2097152)
		m_l2Power(22) = CLng(4194304)
		m_l2Power(23) = CLng(8388608)
		m_l2Power(24) = CLng(16777216)
		m_l2Power(25) = CLng(33554432)
		m_l2Power(26) = CLng(67108864)
		m_l2Power(27) = CLng(134217728)
		m_l2Power(28) = CLng(268435456)
		m_l2Power(29) = CLng(536870912)
		m_l2Power(30) = CLng(1073741824)
	end sub


	Private Function LShift(lValue, iShiftBits)
	    If iShiftBits = 0 Then
	        LShift = lValue
	        Exit Function
	    ElseIf iShiftBits = 31 Then
	        If lValue And 1 Then
	            LShift = &H80000000
	        Else
	            LShift = 0
	        End If
	        Exit Function
	    ElseIf iShiftBits < 0 Or iShiftBits > 31 Then
	        Err.Raise 6
	    End If

	    If (lValue And m_l2Power(31 - iShiftBits)) Then
	        LShift = ((lValue And m_lOnBits(31 - (iShiftBits + 1))) * m_l2Power(iShiftBits)) Or &H80000000
	    Else
	        LShift = ((lValue And m_lOnBits(31 - iShiftBits)) * m_l2Power(iShiftBits))
	    End If
	End Function

	Private Function RShift(lValue, iShiftBits)
	    If iShiftBits = 0 Then
	        RShift = lValue
	        Exit Function
	    ElseIf iShiftBits = 31 Then
	        If lValue And &H80000000 Then
	            RShift = 1
	        Else
	            RShift = 0
	        End If
	        Exit Function
	    ElseIf iShiftBits < 0 Or iShiftBits > 31 Then
	        Err.Raise 6
	    End If
	    
	    RShift = (lValue And &H7FFFFFFE) \ m_l2Power(iShiftBits)

	    If (lValue And &H80000000) Then
	        RShift = (RShift Or (&H40000000 \ m_l2Power(iShiftBits - 1)))
	    End If
	End Function

	Private Function RotateLeft(lValue, iShiftBits)
	    RotateLeft = LShift(lValue, iShiftBits) Or RShift(lValue, (32 - iShiftBits))
	End Function

	Private Function AddUnsigned(lX, lY)
	    Dim lX4
	    Dim lY4
	    Dim lX8
	    Dim lY8
	    Dim lResult
	 
	    lX8 = lX And &H80000000
	    lY8 = lY And &H80000000
	    lX4 = lX And &H40000000
	    lY4 = lY And &H40000000
	 
	    lResult = (lX And &H3FFFFFFF) + (lY And &H3FFFFFFF)
	 
	    If lX4 And lY4 Then
	        lResult = lResult Xor &H80000000 Xor lX8 Xor lY8
	    ElseIf lX4 Or lY4 Then
	        If lResult And &H40000000 Then
	            lResult = lResult Xor &HC0000000 Xor lX8 Xor lY8
	        Else
	            lResult = lResult Xor &H40000000 Xor lX8 Xor lY8
	        End If
	    Else
	        lResult = lResult Xor lX8 Xor lY8
	    End If
	 
	    AddUnsigned = lResult
	End Function

	Private Function F(x, y, z)
	    F = (x And y) Or ((Not x) And z)
	End Function

	Private Function G(x, y, z)
	    G = (x And z) Or (y And (Not z))
	End Function

	Private Function H(x, y, z)
	    H = (x Xor y Xor z)
	End Function

	Private Function I(x, y, z)
	    I = (y Xor (x Or (Not z)))
	End Function

	Private Sub FF(a, b, c, d, x, s, ac)
	    a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac))
	    a = RotateLeft(a, s)
	    a = AddUnsigned(a, b)
	End Sub

	Private Sub GG(a, b, c, d, x, s, ac)
	    a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac))
	    a = RotateLeft(a, s)
	    a = AddUnsigned(a, b)
	End Sub

	Private Sub HH(a, b, c, d, x, s, ac)
	    a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac))
	    a = RotateLeft(a, s)
	    a = AddUnsigned(a, b)
	End Sub

	Private Sub II(a, b, c, d, x, s, ac)
	    a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac))
	    a = RotateLeft(a, s)
	    a = AddUnsigned(a, b)
	End Sub

	Private Function ConvertToWordArray(sMessage)
	    Dim lMessageLength
	    Dim lNumberOfWords
	    Dim lWordArray()
	    Dim lBytePosition
	    Dim lByteCount
	    Dim lWordCount
	    
	    Const MODULUS_BITS = 512
	    Const CONGRUENT_BITS = 448
	    
	    lMessageLength = Len(sMessage)
	    
	    lNumberOfWords = (((lMessageLength + ((MODULUS_BITS - CONGRUENT_BITS) \ BITS_TO_A_BYTE)) \ (MODULUS_BITS \ BITS_TO_A_BYTE)) + 1) * (MODULUS_BITS \ BITS_TO_A_WORD)
	    ReDim lWordArray(lNumberOfWords - 1)
	    
	    lBytePosition = 0
	    lByteCount = 0
	    Do Until lByteCount >= lMessageLength
	        lWordCount = lByteCount \ BYTES_TO_A_WORD
	        lBytePosition = (lByteCount Mod BYTES_TO_A_WORD) * BITS_TO_A_BYTE
	        lWordArray(lWordCount) = lWordArray(lWordCount) Or LShift(Asc(Mid(sMessage, lByteCount + 1, 1)), lBytePosition)
	        lByteCount = lByteCount + 1
	    Loop

	    lWordCount = lByteCount \ BYTES_TO_A_WORD
	    lBytePosition = (lByteCount Mod BYTES_TO_A_WORD) * BITS_TO_A_BYTE

	    lWordArray(lWordCount) = lWordArray(lWordCount) Or LShift(&H80, lBytePosition)

	    lWordArray(lNumberOfWords - 2) = LShift(lMessageLength, 3)
	    lWordArray(lNumberOfWords - 1) = RShift(lMessageLength, 29)
	    
	    ConvertToWordArray = lWordArray
	End Function

	Private Function WordToHex(lValue)
	    Dim lByte
	    Dim lCount
	    
	    For lCount = 0 To 3
	        lByte = RShift(lValue, lCount * BITS_TO_A_BYTE) And m_lOnBits(BITS_TO_A_BYTE - 1)
	        WordToHex = WordToHex & Right("0" & Hex(lByte), 2)
	    Next
	End Function
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #26 (permalink)  
Antiguo 06/10/2007, 18:02
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 10 meses
Puntos: 98
Re: Un módulo de usuarios

Código:
'Continua:
Public Function MD5(sMessage)
	    Dim x
	    Dim k
	    Dim AA
	    Dim BB
	    Dim CC
	    Dim DD
	    Dim a
	    Dim b
	    Dim c
	    Dim d
	    
	    Const S11 = 7
	    Const S12 = 12
	    Const S13 = 17
	    Const S14 = 22
	    Const S21 = 5
	    Const S22 = 9
	    Const S23 = 14
	    Const S24 = 20
	    Const S31 = 4
	    Const S32 = 11
	    Const S33 = 16
	    Const S34 = 23
	    Const S41 = 6
	    Const S42 = 10
	    Const S43 = 15
	    Const S44 = 21

	    x = ConvertToWordArray(sMessage)
	    
	    a = &H67452301
	    b = &HEFCDAB89
	    c = &H98BADCFE
	    d = &H10325476

	    For k = 0 To UBound(x) Step 16
	        AA = a
	        BB = b
	        CC = c
	        DD = d
	    
	        FF a, b, c, d, x(k + 0), S11, &HD76AA478
	        FF d, a, b, c, x(k + 1), S12, &HE8C7B756
	        FF c, d, a, b, x(k + 2), S13, &H242070DB
	        FF b, c, d, a, x(k + 3), S14, &HC1BDCEEE
	        FF a, b, c, d, x(k + 4), S11, &HF57C0FAF
	        FF d, a, b, c, x(k + 5), S12, &H4787C62A
	        FF c, d, a, b, x(k + 6), S13, &HA8304613
	        FF b, c, d, a, x(k + 7), S14, &HFD469501
	        FF a, b, c, d, x(k + 8), S11, &H698098D8
	        FF d, a, b, c, x(k + 9), S12, &H8B44F7AF
	        FF c, d, a, b, x(k + 10), S13, &HFFFF5BB1
	        FF b, c, d, a, x(k + 11), S14, &H895CD7BE
	        FF a, b, c, d, x(k + 12), S11, &H6B901122
	        FF d, a, b, c, x(k + 13), S12, &HFD987193
	        FF c, d, a, b, x(k + 14), S13, &HA679438E
	        FF b, c, d, a, x(k + 15), S14, &H49B40821
	    
	        GG a, b, c, d, x(k + 1), S21, &HF61E2562
	        GG d, a, b, c, x(k + 6), S22, &HC040B340
	        GG c, d, a, b, x(k + 11), S23, &H265E5A51
	        GG b, c, d, a, x(k + 0), S24, &HE9B6C7AA
	        GG a, b, c, d, x(k + 5), S21, &HD62F105D
	        GG d, a, b, c, x(k + 10), S22, &H2441453
	        GG c, d, a, b, x(k + 15), S23, &HD8A1E681
	        GG b, c, d, a, x(k + 4), S24, &HE7D3FBC8
	        GG a, b, c, d, x(k + 9), S21, &H21E1CDE6
	        GG d, a, b, c, x(k + 14), S22, &HC33707D6
	        GG c, d, a, b, x(k + 3), S23, &HF4D50D87
	        GG b, c, d, a, x(k + 8), S24, &H455A14ED
	        GG a, b, c, d, x(k + 13), S21, &HA9E3E905
	        GG d, a, b, c, x(k + 2), S22, &HFCEFA3F8
	        GG c, d, a, b, x(k + 7), S23, &H676F02D9
	        GG b, c, d, a, x(k + 12), S24, &H8D2A4C8A
	            
	        HH a, b, c, d, x(k + 5), S31, &HFFFA3942
	        HH d, a, b, c, x(k + 8), S32, &H8771F681
	        HH c, d, a, b, x(k + 11), S33, &H6D9D6122
	        HH b, c, d, a, x(k + 14), S34, &HFDE5380C
	        HH a, b, c, d, x(k + 1), S31, &HA4BEEA44
	        HH d, a, b, c, x(k + 4), S32, &H4BDECFA9
	        HH c, d, a, b, x(k + 7), S33, &HF6BB4B60
	        HH b, c, d, a, x(k + 10), S34, &HBEBFBC70
	        HH a, b, c, d, x(k + 13), S31, &H289B7EC6
	        HH d, a, b, c, x(k + 0), S32, &HEAA127FA
	        HH c, d, a, b, x(k + 3), S33, &HD4EF3085
	        HH b, c, d, a, x(k + 6), S34, &H4881D05
	        HH a, b, c, d, x(k + 9), S31, &HD9D4D039
	        HH d, a, b, c, x(k + 12), S32, &HE6DB99E5
	        HH c, d, a, b, x(k + 15), S33, &H1FA27CF8
	        HH b, c, d, a, x(k + 2), S34, &HC4AC5665
	    
	        II a, b, c, d, x(k + 0), S41, &HF4292244
	        II d, a, b, c, x(k + 7), S42, &H432AFF97
	        II c, d, a, b, x(k + 14), S43, &HAB9423A7
	        II b, c, d, a, x(k + 5), S44, &HFC93A039
	        II a, b, c, d, x(k + 12), S41, &H655B59C3
	        II d, a, b, c, x(k + 3), S42, &H8F0CCC92
	        II c, d, a, b, x(k + 10), S43, &HFFEFF47D
	        II b, c, d, a, x(k + 1), S44, &H85845DD1
	        II a, b, c, d, x(k + 8), S41, &H6FA87E4F
	        II d, a, b, c, x(k + 15), S42, &HFE2CE6E0
	        II c, d, a, b, x(k + 6), S43, &HA3014314
	        II b, c, d, a, x(k + 13), S44, &H4E0811A1
	        II a, b, c, d, x(k + 4), S41, &HF7537E82
	        II d, a, b, c, x(k + 11), S42, &HBD3AF235
	        II c, d, a, b, x(k + 2), S43, &H2AD7D2BB
	        II b, c, d, a, x(k + 9), S44, &HEB86D391
	    
	        a = AddUnsigned(a, AA)
	        b = AddUnsigned(b, BB)
	        c = AddUnsigned(c, CC)
	        d = AddUnsigned(d, DD)
	    Next
	    
	    MD5 = LCase(WordToHex(a) & WordToHex(b) & WordToHex(c) & WordToHex(d))
	End Function

End Class
%>
Como siempre su implementacion:

Código:
'Encriptamos el string "webmaster"
Set ObjEncriptar = new encriptar
Response.Write(ObjEncriptar.MD5("webmaster"))
Set ObjEncriptar = Nothing
Tarea 2:
Encriptar pwd para el primer usuario de nuestro sistema e introducirlo a la base de datos.

En la siguiente ocasion agregaremos esto a la logica de nuestro formulario y comenzaremos a crear el backend de usuarios.

Saludos
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway

Última edición por u_goldman; 06/10/2007 a las 18:21
  #27 (permalink)  
Antiguo 07/10/2007, 10:29
Avatar de a83
a83
 
Fecha de Ingreso: noviembre-2005
Ubicación: Santiago de chile
Mensajes: 637
Antigüedad: 19 años
Puntos: 1
Re: Un módulo de usuarios

una cosnulta estoy siguiendo paso a paso esto , pero me aroja el siguiente error,


erro!:.
Cita:
Tipo de error:
Páginas Active Server, ASP 0126 (0x80004005)
No se encontró el archivo de inclusión "..conponentes/usuario.asp".
/geochilesa/intranet/componentes/usuario.asp, línea 38
codigo:

Código PHP:
Private sub Class_Initialize
        m_id 
= -1
        m_uname 
""
        
m_pwd ""
    
End sub

End 
Class
%>

Okya podemos probar nuestra clase

<!--#include file = "..conponentes/usuario.asp"-->
<%
Dim ObjUsuario
Set ObjUsuario 
= new usuario 


no entinedo que pueda ser .
  #28 (permalink)  
Antiguo 07/10/2007, 11:44
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 10 meses
Puntos: 98
Re: Un módulo de usuarios

Cita:
Iniciado por a83 Ver Mensaje
una cosnulta estoy siguiendo paso a paso esto , pero me aroja el siguiente error,


erro!:.


codigo:

Código PHP:
Private sub Class_Initialize
        m_id 
= -1
        m_uname 
""
        
m_pwd ""
    
End sub

End 
Class
%>

Okya podemos probar nuestra clase

<!--#include file = "..conponentes/usuario.asp"-->
<%
Dim ObjUsuario
Set ObjUsuario 
= new usuario 


no entinedo que pueda ser .
Hola, el problema es que estas tratando de llamar a una carpeta llamada conponentes, cuando nuestro ejercicio tiene una carpeta llamada componentes, tambien, asegurate que la ruta que estas usando sea la correcta: "..conponentes/" no es una ruta valida, podria ser ../componentes/ ?

Saludos
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #29 (permalink)  
Antiguo 10/10/2007, 14:32
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 10 meses
Puntos: 98
Re: Un módulo de usuarios

¿Qué creen?
Ya regresé

En la sesión anterior, creamos nuestra clase encriptar y dejamos de tarea ingresar manualmente un usuario a su base de datos con el pass encriptado, de manera tal que podamos utilizar ya nuestra forma de login, entonces solo nos quedaría hacer la implementación de la encripción del pwd:

1. Incluir nuestra clase encriptar hasta arriba para ser ordenados
Código:
<!--#include file = "../componentes/encriptar.asp"-->
2. Implementar la encripcion del pwd:
Código:
	Set ObjUsuario = new usuario
	Set ObjEncriptar = new encriptar
	ObjUsuario.uname = trim(Request.Form("uname"))
	ObjUsuario.pwd = ObjEncriptar.MD5(trim(Request.Form("pwd")))
	Set ObjEncriptar = Nothing
	
	if ObjUsuario.Autentificar() then
        'Guardamos en sesion el id del usuario
        Session("usuarioID") = ObjUsuario.id
		Response.Write("Ahora si ingresaste")
	else
		Set ObjUsuario = Nothing
		Session("usuarioID") = ""
		Session("loginError") = true
		Response.Redirect("login.asp")
	end if
Sencillísimo ¿no es así?
Esto nos asegura que ni el admin de nuestro de sistema sepa los passwords de nuestros usuarios registrados, y necesariamente tendremos que crear algún tipo de sistema para reestablecer nuestra contraseña pues como dijimos, el MD5 es un "hash" unidireccional.


El código de nuestro form de login hasta el momento se debe ver así:
Código:
<!--#include file = "../conexion.asp"-->
<!--#include file = "../componentes/usuario.asp"-->
<!--#include file = "../componentes/encriptar.asp"-->
<!--#include file = "../admin/header.asp"-->
<%
Dim formaHasidoEnviada
Dim ObjUsuario
Dim strError
Dim ObjEncriptar

formaHasidoEnviada = len(Request.Form("formaEnviada")) > 0
strError = ""

if not formaHasidoEnviada then
	if Session("loginError") then
		strError = "Usuario o contraseña incorrectos, por favor intente de nuevo"
		Session.Contents.Remove("loginError")
	end if
	%>
	<div class="error"><%=strError%></div>
	<form action="login.asp" method="post" id="formaAsp">
		<input type="hidden" name="formaEnviada" value="1" />
		<input type="hidden" name="accion" value="ingresar" />
	    
		<fieldset class="forma">
			<legend>Introduzca sus datos de acceso</legend>
			<div class="formaEtiqueta">
				<label for="uname">Usuario:&nbsp;</label>
			</div>
			<div class="formaCampo">
				<input type="text" id="uname" name="uname" value="" maxlength="50" />
			</div>
			<br />
			<div class="formaEtiqueta">
				<label for="pwd">Password:&nbsp;</label>
			</div>
			<div class="formaCampo">
				<input type="password" id="pwd" name="pwd" maxlength="8" value="" />
			</div>
			<br />
			<input type="submit" value="Ingresar" class="formaBoton" />
		</fieldset>
	</form>
<%
else
	Set ObjUsuario = new usuario
	Set ObjEncriptar = new encriptar
	ObjUsuario.uname = trim(Request.Form("uname"))
	ObjUsuario.pwd = ObjEncriptar.MD5(trim(Request.Form("pwd")))
	Set ObjEncriptar = Nothing
	
	if ObjUsuario.Autentificar() then
        'Guardamos en sesion el id del usuario
        Session("usuarioID") = ObjUsuario.id
		Response.Write("Ahora si ingresaste")
	else
		Set ObjUsuario = Nothing
		Session("usuarioID") = ""
		Session("loginError") = true
		Response.Redirect("login.asp")
	end if
end if
%>
<!--#include file = "../admin/footer.asp"-->
En unos minutos, crearemos el index de nuestro administrador.

Salud
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
  #30 (permalink)  
Antiguo 10/10/2007, 15:04
Avatar de u_goldman
Moderador
 
Fecha de Ingreso: enero-2002
Mensajes: 8.031
Antigüedad: 22 años, 10 meses
Puntos: 98
Re: Un módulo de usuarios

Hola de nuevo, primero que nada, me di cuenta que de acuerdo a mi costumbre estaba desordenando todo, ya teniamos una serie de archivos en la raiz del folder admin que no tenian por que estar ahi, asi que me permiti crear un nuevo folder llamado controles, en el cual pondremos todo los controles que vayamos creando para nuestro admin, footer y header incluidos, de tal manera que nuestro directorio admin deberia quedar asi:

Código:
admin
|
|--controles
    |
    |--footer.asp
    |--header.asp
    |--autentificar.asp
|
|--index.asp
|--login.asp
En negritas los nuevos folders/archivos

Ahora, como cambiamos la ruta de algunos de los archivos que ya estabamos ocupando, tambien tenemos que cambiar la ruta de las directivas include de estos archivos, de manera tal que los includes en login.asp, quedan de la siguiente manera:

Código:
<!--#include file = "../conexion.asp"-->
<!--#include file = "../componentes/usuario.asp"-->
<!--#include file = "../componentes/encriptar.asp"-->
<!--#include file = "../admin/controles/header.asp"-->
.
.
.
.
<!--#include file = "../admin/controles/footer.asp"-->
Ahora si...

Siempre que hagamos una zona protegida, tenemos que asegurarnos que aquellos archivos que viven de manera protegida, no puedan ser accesibles mediante URL directamente, para esto con frecuencia nos valemos de un archivo asp que evalúa una sesión previamente creada en nuestra forma de login (session("usuarioID")), si esta sesión no existe o no tiene valor, entonces simplemente refgirigimos a nuestra forma de login, la ventaja de poner esta directiva en un archivo aparte emulando un control, es que lo podemos reutilizar en cualquier lado.

Abrimos nuestro archivo controles/autentificar.asp y escribimos lo siguiente:
Código:
<%
if len(Session("usuarioID")) = 0 then
	Response.Redirect("../admin/login.asp")
end if
%>
Básicamente solo estamos diciendo que si no existe la sesion o no tiene valor, lo mande a volar

Ahora comencemos la verdadera diversión, hasta aquí hemos creado nuestras clases y el formulario pero todo esta un poco disperso...vamos a integrarlo

Abrimos nuestro archivo index.asp y escribimos este código:
Código:
<!--#include file = "../admin/controles/auntentificar.asp"-->
<!--#include file = "../conexion.asp"-->
<!--#include file = "../componentes/usuario.asp"-->
<%
Dim ObjUsuario
Set ObjUsuario = new usuario

ObjUsuario.id = Session("usuarioID")
if ObjUsuario.ObtenerDatos() then
%>
	<!--#include file = "../admin/controles/header.asp"-->
	<div class="usuario_datos">Cuenta: <a href="#"><%=ObjUsuario.uname%></a></div>
	<!--#include file = "../admin/controles/footer.asp"-->
<%
	Set ObjUsuario = Nothing
else
	Set ObjUsuario = Nothing
	Session.Contents.Remove("usuarioID")
	Response.Redirect("../admin/login.asp")
end if
%>
La idea del código es la siguiente:

1. Incluimos los archivos que necesitaremos para la autentificación de nuestro usuario

2. Si pasa la primera aduana (que la sesion exista y tenga valor), entonces creamos un nuevo objeto llamado ObjUsuario y de acuerdo con el valor de la sesion obtenida en el form de login que debe ser ni mas ni menos que el id del usuario, obtenemos sus datos mediante nuestro método ObtenerDatos() que creamos en sesiones pasadas.

3. Si existe este usuario, entonces comenzamos a devolver el HTML correspondiente y como ya tenemos todas sus propiedades, "pintamos" su username en un link que ya después le daremos uso.

4. Si no se encuentra este usuario, redirigimos a login.asp, pero quitamos la sesion usuarioID pues si tiene valor pero es incorrecto.

Un ajuste más a nuestra forma de login es el siguiente:

Código:
	if ObjUsuario.Autentificar() then
        'Guardamos en sesion el id del usuario
        Session("usuarioID") = ObjUsuario.id
		'Response.Write("Ahora si ingresaste")
                 Response.Redirect("index.asp")
	else
Y esto es todo por hoy
__________________
"El hombre que ha empezado a vivir seriamente por dentro, empieza a vivir más sencillamente por fuera."
-- Ernest Hemingway
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 2 personas




La zona horaria es GMT -6. Ahora son las 20:39.