PDA

Ver la Versión Completa : Validacion de usuarios


fedelphi
24-05-2007, 00:10:52
Hola de nuevo, quiero hacer que el programa me pida usuario y clave antes de entrar en la pantalla principal del mismo, entonces como se hace para que solo aparezca esta pantalla y quede a la espera del ingreso del usuario? y una vez realizado esto, verificaria en una tabla los datos y en caso de ser correctos recupero el id_usuario y lo coloco en una variable privada o publica de la pantalla principal que se crea con el proyecto y mostraria esta, es esta la forma correcta de realizarlo?
gracias

FGarcia
24-05-2007, 00:20:36
Hola!

Una busqueda en el foro te da suficientes resultados, algunos de ellos:

http://www.clubdelphi.com/foros/showthread.php?t=22997&highlight=form+login
http://www.clubdelphi.com/foros/showthread.php?t=33307&highlight=form+login
http://www.clubdelphi.com/foros/showthread.php?t=36265&highlight=restringir+acceso
http://www.clubdelphi.com/foros/showthread.php?t=17947&highlight=form+login

En la seccion de trucos hay uno para esto que tu quieres pero ese te dejo que lo busques.

ElDioni
24-05-2007, 18:10:30
en la unidad principal del proyecto, tengo puesto lo siguiente:

var
frmacceso:tfrmacceso;
begin
Application.Initialize;
frmacceso:=tfrmacceso.create(nil);
if frmacceso.Showmodal=mrOK then
begin
frmacceso.Free;
Application.CreateForm(TFrmPresAdh, FrmPresAdh);
...
Application.Run;
Application.Terminate;
end
else
begin
frmacceso.free;
end;
end.

y luego desde el formulario de acceso, se comprueba el nombre de usuario y la contraseña si son correctos entonces modalresult:=MROK y si no modalresult:=MRCANCEL.

Un saludo

vtdeleon
25-05-2007, 02:23:11
Run y terminate en el mismo bloque? Seguro que te funciona?


var
frmacceso:tfrmacceso;
begin
Application.Initialize;
frmacceso:=tfrmacceso.create(nil);
if frmacceso.Showmodal=mrOK then
begin
Application.CreateForm(TFrmPresAdh, FrmPresAdh);
...
Application.Run;
end
frmacceso.free;
end.Creo que asi está mejor.

Maury Manosalva
25-05-2007, 19:32:59
with QryConsultas do
begin
close;
SQL.Clear;
consulta := 'Select * from TabUsuarios where IdUsuario ='+char(39)+ txtUsuario.Text+char(39)+
'and ConUsuario ='+chr(39) + txtcontrasena.Text+char(39);
valor := txtUsuario.Text;
SQL.Add(consulta);
Open;
If (RecordCount=1) then


si es igual a 1 pasa a lo que quieres que haga, de lo contrario un application.terminate

vtdeleon
26-05-2007, 01:04:12
:confused:
Saludos

ElDioni
29-05-2007, 18:19:55
Vtdeleon tienes razon, lo pegaría sin darme cuenta, como lo modifique antes de pegar el codigo, para que quedara mas claro, al final parece casi lo complico más.

seoane
29-05-2007, 18:58:32
Run y terminate en el mismo bloque? Seguro que te funciona?

Pues curiosamente, puede que funcione. Ten en cuenta que dentro de "Run" se ejecuta un bucle que no finaliza hasta que la aplicación se termina.

repeat
....
until Terminated;

Así que no ejecutaríamos el método "Terminate" hasta que la aplicación este ya por finalizar. Es decir, la cosa no creo que de error, pero tampoco tiene mucho sentido. :p

vtdeleon
30-05-2007, 00:39:45
Saludos
Así que no ejecutaríamos el método "Terminate" hasta que la aplicación este ya por finalizar.Tienez razón.
Es decir, la cosa no creo que de error, pero tampoco tiene mucho sentido. Asi es...

cHackAll
30-05-2007, 01:54:56
...consulta := 'Select * from TabUsuarios where IdUsuario ='+char(39)+ txtUsuario.Text+char(39)+
'and ConUsuario ='+chr(39) + txtcontrasena.Text+char(39);
...

creo que con un "' or 'x' = 'x" estaríamos haciendo "SQL Injection"... NO aconsejo usar de esta forma al SQL.
Saludos

fedelphi
04-06-2007, 21:59:57
Hola, muchas gracias por las respuestas, he puesto el codigo asi,
var
usuario:TFValidaUsr;
begin

Application.Initialize;
Application.CreateForm(Tmodulodatos, modulodatos);

usuario:=TFValidaUsr.create(nil);
if usuario.showmodal=mrOK then
begin
usuario.Free;
Application.CreateForm(TFPrincipal, FPrincipal);
Application.CreateForm(TFCierreventa, FCierreventa);
Application.Run;

end;
Application.Terminate;

pero si el showmodal no es mrOK, me da un error de 'Access violation at address...', y ademas la tabla de usuarios tiene un campo que indica si tienen permiso a todo o solo a ingreso de datos, como puedo manejar eso? Yo pensaba crear una variable global y asignarla pero ahora no se donde definirla, tomar su valor o asignarla:confused:.
Gracias
Fede

sitrico
05-06-2007, 00:02:35
Prueba con:

var
// usuario:TFValidaUsr; no lo necesitas
mr : Integer;
begin

Application.Initialize;
Application.CreateForm(Tmodulodatos, modulodatos);

With TFValidaUsr.create(nil) do
Begin
Try
mr := showmodal;
// dentro de este formulario debes leer las variables/permisos que necesites,
// Define las variables en Tmodulodatos ej: modulodatos.NivelAcceso, modulodatos.IdUsuario
Finally
free;
End;
End;

if mr=mrOK then
begin
Application.CreateForm(TFPrincipal, FPrincipal);
Application.CreateForm(TFCierreventa, FCierreventa);
Application.Run;

end;
Application.Terminate;

Aunque te recomiendo que definas un registro y una variable en modulo datos:

Type tRegUsuario = record
IdUsuario : integer;
Nombre : ShortString;
NivelAcceso : Byte;
// lo que necesites
End;

Var
Usuario = tRegUsuario;

fedelphi
05-06-2007, 02:13:06
Asi es sitrico, lo he resuelto con un registro y el form de validacion lo largo en el oncreate del form principal de la sig manera:
procedure TFPrincipal.FormCreate(Sender: TObject);
var
usuario:TFValidaUsr;
begin
usuario:=TFValidaUsr.create(nil);
if usuario.showmodal<>mrOK then
begin
usuario.Free;
Application.Terminate;
end;
end;

esta bien hacerlo de esta manera, que ventajas tiene hacerlo de la otra manera?
y para validar al usuario definí un procedure en la base firebird y quedo asi
with modulodatos.ibspvalidausr do
begin
parambyname('PELOGIN').asstring:=Elogin.Text;
parambyname('PECLAVE').asstring:=EClave.text;
execproc;
if parambyname('PSVALIDADO').asstring='si' then
begin
ModalResult:=mrOK;
FPrincipal.usuario_actual.login:=ELogin.text;
FPrincipal.usuario_actual.id_usuario:=parambyname('PSID_USUARIO').AsInteger;
FPrincipal.usuario_actual.administrador:=parambyname('PSPERMISO').asInteger;

end
else
begin
ModalResult:=mrCancel;
showmessage('Usuario inválido');
end;
end;
y al registro lo defino asicurrent_usr=record
login:string;
administrador:integer;
id_usuario:integer;
end;
luego creo una instancia de este el la parte publica del form principal para accederlo desde cualquier form.
Es correcto hacerlo de esta manera, es la primera vez que hago una validación de usuarios y me gustaria escuchar alguna opinion. Gracias
Fede

AzidRain
05-06-2007, 03:23:00
A mi me funciona esto de forma muy simple:
Pongo este código en el onshow de la ventana principal


FLogin := TFLogin.Create(self,Datos.Conexion);
Flogin.Execute;
If Not FLogin.LoggedIn Then Close
Else
PonLineaEstado;


FLogin es una ventanita de captura que pide usuario y contraseña, de paso en el mismo objeto guardo los datos de usuario,nivel, nombre, etc. esta ventana le digo al IDE que me la cree automáticamente y ahi la dejo para acceder a los datos del usuario logeado desde cualquier otro lado del programa. Es rudimentario pero me ha funcionado muy bien

Aqui el codigo integro de la unidad FLogin, aclaro que uso Zeos para hacer la conexion a BD MySQL


unit UFLogin;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ExtCtrls, DB, ZAbstractRODataset, ZDataset,
ZAbstractDataset, Konst, cxButtons, cxLookAndFeelPainters, Udatos,
ZConnection;

type
TFLogin = class(TForm)
Panel1: TPanel;
Label1: TLabel;
ELogin: TEdit;
EPassword: TEdit;
Label2: TLabel;
ZUsuarios: TZQuery;
Image1: TImage;
BotIngresar: TcxButton;
constructor Create(owner:TComponent; con:TZConnection);
procedure BotIngresarClick(Sender: TObject);
private
{ Private declarations }
procedure AceptaDatos;
procedure ResetDatos;
public
{ Public declarations }
UsuarioActual : String;
NivelActual : Integer;
LoggedIn : Boolean;
SucursalActual : String;
NombreActual : String;
UBicacionActual : String;
tries:integer;

procedure Execute;

end;

var fLogin:TFLogin;
implementation

{$R *.dfm}

constructor TFLogin.Create(owner: TComponent; con: TZConnection);
begin
inherited create(owner);
LoggedIN := FALSE;
tries := 1;
ZUsuarios.Connection := con; // le paso la conexion MySQL
end;

procedure TFLogin.Execute;
var tries:Integer;
Begin

If ZUsuarios.Connection.Connected Then // ZUsuarios es la tabla
Begin
ShowModal
end
else
raise Exception.Create('La conexión al servidor debe estar disponible');
end;


procedure TFLogin.BotIngresarClick(Sender: TObject);
begin
If ZUsuarios.Active Then ZUsuarios.Close;
ZUsuarios.ParamByName('LOGIN').AsString := ELogin.Text;
ZUsuarios.ParamByName('PASSW').AsString := EPassword.Text;
ZUsuarios.Open;
If ZUsuarios.RecordCount> 0 Then
Begin
AceptaDatos;
modalResult := mrOk;
Close;
end
else
Begin
MessError('Usuario o Contraseña Incorrecta'); // Sustituir por ShowMessage o algun otro
If tries=3 Then
Begin
modalResult := mrCancel;
Close;
end
else
ResetDatos;
end;
end;

procedure TFLogin.AceptaDatos;
begin
LoggedIN := TRUE;
UsuarioActual := ZUsuarios.FieldBYName('LOGIN').AsString;
NivelActual := ZUsuarios.FieldBYName('NIVEL').AsInteger;
SucursalActual:= ZUsuarios.FieldBYName('SUCURSAL').AsString;
NombreActual := ZUsuarios.FieldBYName('NOMBRE').AsString;
end;

procedure TFLogin.ResetDatos;
begin
Elogin.Clear;
EpassWord.Clear;
ELogin.SetFocus;
Inc(tries);
end;

end.


Les repito que a mi me ha funcionado muy bien y obviamente le faltan toques de elegancia pero ahi se los dejo.

Para saber por ejemplo que usuario esta dentro del sistema en cualquier otro lado del programa, solo agrego la unidad al uses y accedo FLogin para conocerlo.
Te anexo el código y el form.

fedelphi
05-06-2007, 03:59:35
Muchas gracias azidrain me viene muy bien esto ya que estoy aprendiendo, lo vere con mas detalle.
Fede

sitrico
06-06-2007, 23:59:34
fedelphi
que ventajas tiene hacerlo de la otra manera?

En el primer caso (el mío) no se ve el form principal de la aplicación en el 2do (el tuyo), si se ve. Ventajas/Desventajas reales no encuentro.

AzidRain
A mi me funciona esto de forma muy simple:
Pongo este código en el onshow de la ventana principal


FLogin := TFLogin.Create(self,Datos.Conexion);
Flogin.Execute;
If Not FLogin.LoggedIn Then Close
Else
PonLineaEstado;FLogin

¿ No liberas FLogin (Flogin.free.) ?

¿ cada vez que se ejecuta el onShow se crea un nuevo formulario ?

Creo que tienes fugas de recursos. :rolleyes:

AzidRain
07-06-2007, 01:50:23
No señor, el flogin, se libera hasta que se cierra la aplicación.

Flogin es una ventana pequeña sin adornos solo tiene 2 edits y un boton, no creo que sean tantos recursos como para preocuparse.