Entrada 11 (Bloqueo por IP si usuario no existe en sp_Login y agregar sp_Logout)
Fecha: 25/04/2026
Inicio: [22:38] | Fin: [23:14] || Total: [36 minutos]
Presentes: Sebastián Ramírez Abarca
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
¿QUÉ HICIMOS HOY?
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Se actualizó sp_Login de forma que si se ingresa usernames incorrectos 5 veces en 20 minutos desde una misma IP se bloqueará por IP.
Se avanzó con store procedures: se hizo sp_Logout.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PROBLEMAS ENCONTRADOS Y CÓMO SE RESOLVIERON
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
No hubo problemas puesto que el código agregado es sencillo.
Aclarar que no se ha probado el programa con estos cambios aún.
Aclarar que no se ha probado el programa con estos cambios aún.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
DUDAS Y DIVERGENCIAS DE CRITERIO
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. No surgió ninguna duda en esta sesión.
2. Debido a que en este sesión solo participó una persona no hubo divergencias.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
AVANCE DEL CÓDIGO
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
código actualizado completo de sp_Login:
USE VacacionesDB;
GO
-- =====================================================
-- SP: Login de usuario
-- =====================================================
DROP PROCEDURE IF EXISTS sp_Login;
GO
CREATE PROCEDURE sp_Login
@inUsername VARCHAR(128),
@inPassword VARCHAR(128),
@inIpPostIn VARCHAR(64),
@inPostTime DATETIME,
@outResultCode INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @idUsuario INT,
@password VARCHAR(128),
@idTipoEventoSuccess INT,
@idTipoEventoFail INT,
@idTipoEventoDisabled INT,
@intentosFallidos INT,
@descripcion VARCHAR(512)
SET @outResultCode = 0;
BEGIN TRY
SELECT @idTipoEventoSuccess = t.id
FROM dbo.TipoEvento t
WHERE t.Nombre = 'Login Exitoso';
SELECT @idTipoEventoFail = t.id
FROM dbo.TipoEvento t
WHERE t.Nombre = 'Login No Exitoso';
SELECT @idTipoEventoDisabled = t.id
FROM dbo.TipoEvento t
WHERE t.Nombre = 'Login deshabilitado';
-- Obtener datos del usuario
-- @idUsuario y @password serán NULL si no existe @inUsername en la BD
SELECT @idUsuario = u.id, @password = u.password
FROM dbo.Usuario u
WHERE u.Username = @inUsername;
-- Verificar que existe usuario
IF @idUsuario IS NULL
BEGIN
-- Contat intentos fallidos por IP en los ultimos 20 min
SELECT @intentosFallidos = COUNT(*)
FROM dbo.BitacoraEvento b
WHERE b.idTipoEvento = @idTipoEventoFail
AND b.IpPostIn = @inIpPostIn
AND b.PostTime >= DATEADD(MINUTE, -20, @inPostTime);
IF @intentosFallidos >= 5
BEGIN
SET @outResultCode = 50003;
INSERT INTO dbo.BitacoraEvento (idTipoEvento, Descripcion, idUsuario, IpPostIn, PostTime)
VALUES (@idTipoEventoDisabled, NULL, NULL, @inIpPostIn, @inPostTime)
RETURN;
END
SET descripcion = 'Intento: ' + CAST(@intentosFallidos + 1 AS VARCHAR(10))
+ ' | Error: ' + (SELECT Descripcion FROM dbo.Error WHERE Codigo = 50001);
INSERT INTO dbo.BitacoraEvento (idTipoEvento, Descripcion, idUsuario, IpPostIn, PostTime)
VALUES (@idTipoEventoFail, @descripcion, NULL, @inIpPostIn, @inPostTime);
SET @outResultCode = 50001;
RETURN;
END
-- Contar intentos fallidos en los ultimos 20 min
SELECT @intentosFallidos = COUNT(*)
FROM dbo.BitacoraEvento b
WHERE b.idTipoEvento = @idTipoEventoFail
AND b.idUsuario = @idUsuario
AND b.IpPostIn = @inIpPostIn
AND b.PostTime >= DATEADD(MINUTE, -20, @inPostTime);
IF @intentosFallidos >= 5
BEGIN
SET @outResultCode = 50003;
INSERT INTO dbo.BitacoraEvento (idTipoEvento, Descripcion, idUsuario, IpPostIn, PostTime)
VALUES (@idTipoEventoDisabled, NULL, @idUsuario, @inIpPostIn, @inPostTime)
RETURN;
END
-- Verficar password
IF @password <> @inPassword
BEGIN
SET @outResultCode = 50002;
SET @descripcion = 'Intento: ' + CAST(@intentosFallidos + 1 AS VARCHAR(10))
+ ' | Error: ' + (SELECT Descripcion FROM dbo.Error WHERE Codigo = 50002);
INSERT INTO dbo.BitacoraEvento (idTipoEvento, Descripcion, idUsuario, IpPostIn, PostTime)
VALUES (@idTipoEventoFail, @descripcion, @idUsuario, @inIpPostIn, @inPostTime);
RETURN;
END
-- Si Login exitoso
INSERT INTO BitacoraEvento (idTipoEvento, Descripcion, idUsuario, IpPostIn, PostTime)
VALUES (@idTipoEventoSuccess, 'Exitoso', @idUsuario, @inIpPostIn, @inPostTime);
SET @outResultCode = 0;
END TRY
BEGIN CATCH
INSERT INTO DBError (UserName, Number, State, Severity, Line, [Procedure], Message, DateTime)
VALUES (
SYSTEM_USER,
ERROR_NUMBER(),
CAST(ERROR_STATE() AS VARCHAR(32)),
CAST(ERROR_SEVERITY() AS VARCHAR(32)),
ERROR_LINE(),
ISNULL(ERROR_PROCEDURE(), 'sp_Login'),
ERROR_MESSAGE(),
GETDATE()
);
SET @outResultCode = 50008;
END CATCH
END;
GO
sp_Logout:
USE VacacionesDB;
GO
-- =====================================================
-- SP: Logout de usuario
-- =====================================================
DROP PROCEDURE IF EXISTS sp_Logout;
GO
CREATE PROCEDURE sp_Logout
@inIdUsuario INT,
@inIpPostIn VARCHAR(64),
@inPostTime DATETIME,
@outResultCode INT OUTPUT
AS
BEGIN
SET NOCOUNT ON
DECLARE @idTipoEventoLogout INT;
SET @outResultCode = 0;
BEGIN TRY
SELECT @idTipoEventoLogout = t.id
FROM dbo.TipoEvento t
WHERE t.Nombre = 'Logout';
INSERT INTO dbo.BitacoraEvento (idTipoEvento,Descripcion, idUsuario, IpPostIn, PostTime)
VALUES (@idTipoEventoLogout, NULL, @inIdUsuario, @inIpPostIn, @inPostTime)
SET @outResultCode = 0;
END TRY
BEGIN CATCH
INSERT INTO dbo.DBError (UserName, Number, State, Severity, Line, [Procedure], Message, DateTime)
VALUES (
SYSTEM_USER,
ERROR_NUMBER(),
CAST(ERROR_STATE() AS VARCHAR(32)),
CAST(ERROR_SEVERITY() AS VARCHAR(32)),
ERROR_LINE(),
ISNULL(ERROR_PROCEDURE(), 'sp_Logout'),
ERROR_MESSAGE(),
GETDATE()
);
SET @outResultCode = 50008
END CATCH
END;
GO
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
MORALEJAS / BUENAS PRÁCTICAS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Si se utiliza la configuración de autocompletar en Visual Studio Code al hacer commit se registrará que ese commit fue co-trabajado con Copilot.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PRÓXIMA SESIÓN: ¿QUÉ SIGUE?
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- Integrar sp_GetError a capa lógica.
Comentarios
Publicar un comentario