简体   繁体   English

在存储过程中验证用户

[英]Authenticate user in stored procedure

I am new to sql and I am not sure what's wrong with my stored procedure. 我是sql的新手,我不确定存储过程出了什么问题。

User inputs user name & password which are my input parameters and if it is correct then return 'Login Success', if UN is incorrect than return 'Incorrect UN' or if PW is incorrect than return 'Incorrect PW'. 用户输入的用户名和密码是我的输入参数,如果正确,则返回“登录成功”,如果UN不正确,则返回“ Invalid UN”,或者PW不正确,则返回“ Invalid PW”。 In the stored procedure I have an IF Else statement and it is only hitting the first IF statement not other. 在存储过程中,我有一个IF Else语句,它仅击中第一个IF语句,其他都没有。

Please have a look my stored procedure: 请看看我的存储过程:

CREATE PROCEDURE [dbo].[AuthenticateUser]
@UserName varchar(15),
@Password varchar(15),
@Role varchar(25) OUTPUT
AS
    SET NOCOUNT ON
BEGIN
    DECLARE @UN VARCHAR(25)
    DECLARE @PW VARCHAR(25)
    SELECT @UN = UserName, @PW = Password FROM LogIn 
        IF (@UN != @UserName COLLATE SQL_Latin1_General_CP1_CS_AS)
            BEGIN
                SET @Role = 'Incorrect User Name'
            END
        ELSE
            BEGIN
                IF (@PW != @Password COLLATE SQL_Latin1_General_CP1_CS_AS)
                    BEGIN
                        SET @Role = 'Incorrect Password'
                    END
                ELSE
                    BEGIN
                        SET @Role = 'Logged in Successfully'
                    END
            END
    SELECT @Role
END

Thank you for your help 谢谢您的帮助

Change it to a SELECT COUNT(1) FROM userLogin.... and then use ExecuteScalar() on the SqlDataReader object. 将其更改为SELECT COUNT(1)from userLogin ....,然后在SqlDataReader对象上使用ExecuteScalar()。

As a side note, it's not a good idea to store your passwords in the DB in plain text, but hash them instead, preferably with a salt value. 附带说明一下,将密码以纯文本格式存储在数据库中不是一个好主意,而是将其散列,最好使用盐值。

You are doing this: 您正在执行此操作:

SELECT @UN = UserName, @PW = Password FROM LogIn 
    IF (@UN != @UserName COLLATE SQL_Latin1_General_CP1_CS_AS)

These comparisions @UN = UserName and @PW = Password should be made in the WHERE clause to help in proper filtering of rows. 这些比较@UN = UserName@PW = Password应该在WHERE子句中进行,以帮助正确过滤行。

Here is the code rewritten (you can change to using your own table name) 这是重写的代码(您可以更改为使用自己的表名)

Drop Table TestLogin 
GO
Create Table TestLogin 
(
UserName VarChar (20),
Password VarChar(20)
)
Insert TestLogin Values ('One', 'Two')
GO




Drop PROCEDURE AuthenticateUser
GO
CREATE PROCEDURE AuthenticateUser
    @UserName varchar(15),
    @Password varchar(15),
    @Role varchar(25) OUTPUT
AS

    If ((SELECT Count (*) From TestLogin Where UserName COLLATE SQL_Latin1_General_CP1_CS_AS = @Username And Password COLLATE SQL_Latin1_General_CP1_CS_AS = @Password) = 0)
    Begin
        If ((SELECT Count (*) From TestLogin Where UserName COLLATE SQL_Latin1_General_CP1_CS_AS = @Username) = 0)
        Begin
            Select @Role = 'Incorrect User Name'
        End
        Else
        Begin
             Select @Role = 'Incorrect Password'
        End
    End
    Else
    Begin
        Select @Role = 'Logged in Successfully'
    End
GO
Declare @Role VarChar (100)
Exec AuthenticateUser 'One', 'Two', @Role Output
Print @Role

Exec AuthenticateUser 'One', 'TwoX', @Role Output
Print @Role

Exec AuthenticateUser 'OneX', 'Two', @Role Output
Print @Role

The three examples provided at the end show you how the procedure behaves when you give it a good login, or either parameter is incorrect. 最后提供的三个示例向您展示了良好的登录过程,或者其中一个参数不正确时,该过程的行为。

Try this instead: 尝试以下方法:

Create PROCEDURE [dbo].[AuthenticateUser]
@UserName varchar(15),
@Password varchar(15),
@Role varchar(25) OUTPUT
AS
    SET NOCOUNT ON
BEGIN

    If Not Exists (Select 1 From LogIn Where UserName = @UserName) Set @Role = 'Incorrect UserName'
    Else If Not Exists (Select 1 From LogIn Where Password = @Password) Set @Role = 'Incorrect Password'
    Else Set @Role = 'Logged in Successfully' 

    Select @Role

END

Generally it is not good idea to give an attacker a cue "name is OK, now guess PWD". 通常,给攻击者提示“名称正确,现在猜PWD”不是一个好主意。 Plus, password should be at least case sensitive. 另外,密码至少应区分大小写。 For this purpose: 以此目的:

select @un=username from LogIn 
where username=@username 
and cast(password as varbinary(max)) = cast(@password as varbinary(max))

if @un is null
   set @role = 'UN or PWD is incorrect'
else
   set @role = 'Success'

If you want to give hints: 如果您想给出提示:

select @un=username from LogIn 
where username=@username 

if @un is null
   set @role = 'UN not found'
else
begin
   select @un=username from LogIn 
   where username=@username 
   and cast(password as varbinary(max)) = cast(@password as varbinary(max))
   if @un is null
      set @role = 'password incorrect'
   else
      set @role = 'Success'
end

PS: I hope username is unique in your table. PS:希望用户名在您的表中是唯一的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM