Your best option here is to create a Stored procedure to handle everything.
On user login, the stored procedure is called with the username and password(Encrypted) for example.
This stored procedure would do the following
- Validate the login.
- Update a Lastlogin timestamp
- write the login audit row (irrespective of successful or unsuccessful login.
This would be the best way to handle the process. I would then wrap the above in a transaction, to ensure that the audit record is always created for any login. If the transaction fails, the user will have to login again.
Here is a very basic example for the sake of keeping it simple. It can definitely be improved on for your specific use case, but this is broken down for easy reading and logic, especially around the password validation as encryption should be used but is not for this example :)
CREATE PROCEDURE ApplicationLogin @Username nvarchar(255), @Password nvarchar(255), @IpAddress
AS
BEGIN
DECLARE @UserID int;
BEGIN TRANSACTION;
SET @UserID = (SELECT UserID FROM Logins WHERE Username = @Username AND Passwword = @Password );
IF @UserID > 0
BEGIN
UPDATE Logins SET LastLogin = GETDATE() WHERE UserID = @UserID;
END
INSERT INTO UserAudit (Username, UserID, Password, IpAddress, TimeStamp)
Values(@Username, @UserID, @Password, @IpAddress, @Timestamp);
COMMIT TRANSACTION;
SELECT @UserID --On your client, check if the returned @UserID is >0. If it is, then successful login. If not, then unsuccessful.
END
The login check and LastLogin Update could probably be combined. You could also use a try catch instead of a transaction. In this case I believe the difference in negligible. Also, as mentioned, you would want to have your passwords encrypted. What i liked to do, was encrypt the password in the client, and only compare encrypted strings. That means you never need to decrypt the password. Its always encrypted and therefore i believe is more secure.