none
Crear procedimiento para Inicio de sesion y validar estado de usuario. RRS feed

  • Pregunta

  • Hola comunidad buen dia,

    Tengo que crear un procedimiento de inicio de sesion, aparte de eso tengo que validar
    el estado del usuario, ACTIVADO O DESACTIVADO. No se si de esta manera estara bien, tal vez me pueden ayuadar a revisarlo y si hay que hacer modificaciones me pueden indicar cuales.

    Debe de funcionar para validar Iniciar Sesion en una pagina Web, esa parte aun no la he hecho, estoy ahorita
    con SQL y tengo dudas con este procedimiento.

    Saludos.

    ALTER PROCEDURE [dbo].[Inicio_Sesion] @Usuario varchar(20), @Clave varchar(20) AS BEGIN Declare @cta int Declare @clv varchar(20) Declare @est int Select @cta = count(*) from Usuarios where Usuario = @Usuario if @cta <= 0 return '-2' Select @est = @Estado from Usuarios where Usuario = @Usuario if @est <= 0 return -3 --Desactivado Select @clv = Convert(varchar(20),DECRYPTBYPASSPHRASE(@Clave,@Usuario)) from Usuarios where Usuario = @Usuario if @clv = @Clave return 0 return @clv END



    viernes, 23 de agosto de 2019 17:18

Respuestas

  • Hola TheRealJoker7:

    Hay varias cosas que yo creo que puedes mejorar.

    La primera, porque contar si existe un usuario, cuando le puedes poner una condición unique a usuario para que la base de datos, se encargue de que no pueda haber dos usuarios idénticos. Si esto lo haces así, solo tienes que preocuparte de que la consulta resuelva algún valor.

    Unique

    https://docs.microsoft.com/es-es/sql/relational-databases/tables/create-unique-constraints?view=sql-server-2017

    No hagas varias lecturas a la tabla, resuelve una sola lectura con todos los valores, y luego condiciona la salida por cada uno de ellos.

    En el segundo Select @est= no puede ser igual a @estado, será a Estado (columna de la tabla)

    No creo que te funcione correctamente ese Convert Varchar(20), y supongo que será el segundo parámetro la columna clave de la base de datos, no una variable.

    Como no has puesto la definición de tu tabla, te voy a aproximar algo más, desde mi punto de vista razonable ese procedure.

    CREATE TABLE USUARIOS
    (USUARIO VARCHAR(20) PRIMARY KEY, 
     CLAVE   VARBINARY(8000), 
     ESTADO  INT NOT NULL
    );
    GO
    INSERT INTO USUARIOS (USUARIO, CLAVE, ESTADO) 
    VALUES 
    ('JAVI'  ,ENCRYPTBYPASSPHRASE('CLAVESEGURA','JaviPwd'  ), 3),
    ('ANA'   ,ENCRYPTBYPASSPHRASE('CLAVESEGURA','AnaPwd'   ),-1),
    ('CARLOS',ENCRYPTBYPASSPHRASE('CLAVESEGURA','CarlosPwd'), 3);

    Si observas el tipo de columna de Clave en la tabla es varBinary(8000), y la clave que utilizo para EncrypByPassPhrase, es la misma para los 3 usuarios.

    CREATE OR ALTER PROCEDURE [dbo].[Inicio_Sesion]
    /* Create or Alter solo válido a partir de SQL 2016 */
    (@Usuario VARCHAR(20), 
     @Clave   VARCHAR(20), 
     @Result  INT OUT
    )
    AS
    
      BEGIN
            DECLARE @clv VARCHAR(200);
            DECLARE @est INT;
            SELECT @est = Estado, 
                   @clv = TRY_CAST(DECRYPTBYPASSPHRASE('CLAVESEGURA', CLAVE) AS VARCHAR(200))
            FROM Usuarios
            WHERE EXISTS
            (
                SELECT *
                FROM usuarios
                WHERE Usuario = @Usuario
            ) AND USUARIO = @Usuario;
    
            IF @EST IS NULL  --ASUMO QUE SI NO HAY ESTADO NO HA LEIDO A NINGÚN USUARIO*/
                SET @Result = -2;
            ELSE
                IF @EST < 0
                    SET @result = -3; -- ESTADO NO VALIDO
                ELSE
                    IF TRY_CAST(@CLV AS VARCHAR(20))= @Clave
                        SET @result = 0 -- USUARIO CORRECTO;
                    ELSE
                        SET @result = -1; -- USUARIO O CLAVE NO VALIDA
            RETURN;
        END;
    

    Cambios reseñables. 

    Un parametro tipo out, para saber que resuelve el procedimiento almacenado.

    Return se debería de usar, para saber que la ejecución ha sido correcta, no el contenido de lo ejecutado, para esto tenemos OUT.

    Ya no utilizo la cuenta y me basta con saber que Usuario es clave primaria o tiene la restricción unique para que no haya 2 y con saber que si la columna estado tiene algo, ha leído al usuario buscado.

    Ejecución

    DECLARE @result INT;
    EXEC [dbo].[Inicio_Sesion] 
         'CARLOS', 
         'CLAVEINCORRECTA', 
         @Result OUT;
    	--- carlos no tiene esta clave
    SELECT @result AS leido;
    GO
    DECLARE @result INT;
    EXEC [dbo].[Inicio_Sesion] 
         'JAVI', 
         'JaviPwd', 
         @Result OUT;
    	--- resultado OK
    SELECT @result AS leido;
    GO
    DECLARE @result INT;
    EXEC [dbo].[Inicio_Sesion] 
         'BUSQUEDANO VALIDA', 
         'DD', 
         @Result OUT;
    	--- USUARIO O CLAVE INCORRECTA
    SELECT @result AS leido;
    GO
    DECLARE @result INT;
    EXEC [dbo].[Inicio_Sesion] 
         'ANA', 
         'DD', 
         @Result OUT;
    	-- ESTADO NO VALIDO
    SELECT @result AS leido;
    GO

    Salida

    Espero te ayude como punto de partida.

    sábado, 24 de agosto de 2019 7:49

Todas las respuestas

  • Hola TheRealJoker7:

    Hay varias cosas que yo creo que puedes mejorar.

    La primera, porque contar si existe un usuario, cuando le puedes poner una condición unique a usuario para que la base de datos, se encargue de que no pueda haber dos usuarios idénticos. Si esto lo haces así, solo tienes que preocuparte de que la consulta resuelva algún valor.

    Unique

    https://docs.microsoft.com/es-es/sql/relational-databases/tables/create-unique-constraints?view=sql-server-2017

    No hagas varias lecturas a la tabla, resuelve una sola lectura con todos los valores, y luego condiciona la salida por cada uno de ellos.

    En el segundo Select @est= no puede ser igual a @estado, será a Estado (columna de la tabla)

    No creo que te funcione correctamente ese Convert Varchar(20), y supongo que será el segundo parámetro la columna clave de la base de datos, no una variable.

    Como no has puesto la definición de tu tabla, te voy a aproximar algo más, desde mi punto de vista razonable ese procedure.

    CREATE TABLE USUARIOS
    (USUARIO VARCHAR(20) PRIMARY KEY, 
     CLAVE   VARBINARY(8000), 
     ESTADO  INT NOT NULL
    );
    GO
    INSERT INTO USUARIOS (USUARIO, CLAVE, ESTADO) 
    VALUES 
    ('JAVI'  ,ENCRYPTBYPASSPHRASE('CLAVESEGURA','JaviPwd'  ), 3),
    ('ANA'   ,ENCRYPTBYPASSPHRASE('CLAVESEGURA','AnaPwd'   ),-1),
    ('CARLOS',ENCRYPTBYPASSPHRASE('CLAVESEGURA','CarlosPwd'), 3);

    Si observas el tipo de columna de Clave en la tabla es varBinary(8000), y la clave que utilizo para EncrypByPassPhrase, es la misma para los 3 usuarios.

    CREATE OR ALTER PROCEDURE [dbo].[Inicio_Sesion]
    /* Create or Alter solo válido a partir de SQL 2016 */
    (@Usuario VARCHAR(20), 
     @Clave   VARCHAR(20), 
     @Result  INT OUT
    )
    AS
    
      BEGIN
            DECLARE @clv VARCHAR(200);
            DECLARE @est INT;
            SELECT @est = Estado, 
                   @clv = TRY_CAST(DECRYPTBYPASSPHRASE('CLAVESEGURA', CLAVE) AS VARCHAR(200))
            FROM Usuarios
            WHERE EXISTS
            (
                SELECT *
                FROM usuarios
                WHERE Usuario = @Usuario
            ) AND USUARIO = @Usuario;
    
            IF @EST IS NULL  --ASUMO QUE SI NO HAY ESTADO NO HA LEIDO A NINGÚN USUARIO*/
                SET @Result = -2;
            ELSE
                IF @EST < 0
                    SET @result = -3; -- ESTADO NO VALIDO
                ELSE
                    IF TRY_CAST(@CLV AS VARCHAR(20))= @Clave
                        SET @result = 0 -- USUARIO CORRECTO;
                    ELSE
                        SET @result = -1; -- USUARIO O CLAVE NO VALIDA
            RETURN;
        END;
    

    Cambios reseñables. 

    Un parametro tipo out, para saber que resuelve el procedimiento almacenado.

    Return se debería de usar, para saber que la ejecución ha sido correcta, no el contenido de lo ejecutado, para esto tenemos OUT.

    Ya no utilizo la cuenta y me basta con saber que Usuario es clave primaria o tiene la restricción unique para que no haya 2 y con saber que si la columna estado tiene algo, ha leído al usuario buscado.

    Ejecución

    DECLARE @result INT;
    EXEC [dbo].[Inicio_Sesion] 
         'CARLOS', 
         'CLAVEINCORRECTA', 
         @Result OUT;
    	--- carlos no tiene esta clave
    SELECT @result AS leido;
    GO
    DECLARE @result INT;
    EXEC [dbo].[Inicio_Sesion] 
         'JAVI', 
         'JaviPwd', 
         @Result OUT;
    	--- resultado OK
    SELECT @result AS leido;
    GO
    DECLARE @result INT;
    EXEC [dbo].[Inicio_Sesion] 
         'BUSQUEDANO VALIDA', 
         'DD', 
         @Result OUT;
    	--- USUARIO O CLAVE INCORRECTA
    SELECT @result AS leido;
    GO
    DECLARE @result INT;
    EXEC [dbo].[Inicio_Sesion] 
         'ANA', 
         'DD', 
         @Result OUT;
    	-- ESTADO NO VALIDO
    SELECT @result AS leido;
    GO

    Salida

    Espero te ayude como punto de partida.

    sábado, 24 de agosto de 2019 7:49
  • Listo amigo, mil gracias.
    viernes, 30 de agosto de 2019 15:43
  • De nada
    viernes, 30 de agosto de 2019 17:22
  •  Amigo, una consulta.

    Y mil disculpas por las molestias.

    Como puedo crear una funcion o procedimiento que me ayude a cambiar la clave de los usuarios de mi base de datos?

    Saludos.
    miércoles, 18 de septiembre de 2019 22:02
  • Hola TheRealJoker7:

    CREATE TABLE USUARIOS
    (USUARIO VARCHAR(20) PRIMARY KEY, 
     CLAVE   VARBINARY(8000), 
     ESTADO  INT NOT NULL
    );
    GO
    INSERT INTO USUARIOS (USUARIO, CLAVE, ESTADO) 
    VALUES 
    ('JAVI'  ,ENCRYPTBYPASSPHRASE('CLAVESEGURA','JaviPwd'  ), 3),
    ('ANA'   ,ENCRYPTBYPASSPHRASE('CLAVESEGURA','AnaPwd'   ),-1),
    ('CARLOS',ENCRYPTBYPASSPHRASE('CLAVESEGURA','CarlosPwd'), 3);
    GO
    /* hasta aquí era el escenario ya planteado */
    --------------------------------------------
    CREATE PROCEDURE SP_CAMBIARPASSWORD 
    (
        @USUARIO VARCHAR(20),
        @NEWPASS VARCHAR(20)
    )
    AS
    
        UPDATE USUARIOS 
    	   SET CLAVE = ENCRYPTBYPASSPHRASE('CLAVESEGURA',@NEWPASS)
    		  WHERE USUARIO = @USUARIO;
    
    RETURN;
    
    GO
    /* Ejecución del sp */
    EXEC SP_CAMBIARPASSWORD 'JAVI','NUEVACLAVE'
    GO
    
    SELECT *, 
    TRY_CAST((DECRYPTBYPASSPHRASE('CLAVESEGURA',CLAVE)) AS varchar(200)) 
    FROM USUARIOS U
    Salida


    jueves, 19 de septiembre de 2019 3:43
  • Gracias amigos.

    Saludos.
    jueves, 19 de septiembre de 2019 17:48