做系统的登录操作时,
①通过用户名从数据库中获取密码,然后用该密码与用户输入密码比较,判断是否登录成功
select userpwd from user where username=@userName
②直接将用户名和密码一起传入数据库,获取用户信息,获取到了,表示登录成功过
select * from user where username=@userName and userpwd=@userPwd
这两种方法哪种好一点,又好在哪里,欢迎大家来讨论(安全方面、性能方面等)
第一种好点,因为可以得到用户是否存在,以及密码是否匹配两种错误提示,如果还需要用户状态的话,还可以得到用户是状态是否有效的提示。
性能没什么差异,从安全角度来讲,看似第二种更安全,因为密码不会提取到进程中来,但仔细想想,如果因为密码存储到了内存中造成密码泄露,那么攻击者首先就取得了系统的权限,既然攻击者都能在系统中运行它的代码了,那么它就可以拿到你的数据库的连接字符串,从而直接从数据库中查询。
谢谢,
一般我们登陆之后,同时需要获取用户的基本信息,也就是说,第一种需要连接2次数据库,而第二种需要连接一次数据库,而很多企业系统都会面临短时段内大并发操作,这又该如何取舍呢?
再说现在主流的登录提示是“用户名与密码不匹配”,根本不会提示用户名已存在,防止暴力破解
@Shinto Ruan: 我还是给你分析下,首先,要获取用户基本信息,就需要先验证密码,因此首先读取密码,验证通过后再读取用户基本信息,这就是你的“两次连接数据库”;那么我们再来看你的第二种方法,你仍然需要先验证密码,那么你是不是要连接一次数据库,然后验证通过后,你再读取用户基本信息,是不是又要连接一次数据库,那么这里同样也是两次,跟第一种方式没有区别。
再来说安全提示的问题,这个提示是给用户的,但是你的系统还有给自己的提示,这就是我们经常说的异常屏蔽和提升,详细的错误是给维护人员和开发人员看的,而模糊或笼统的提示是处于安全考虑给用户看的。当一个用户看到“用户名与密码不匹配”时,那么当他给客服打电话时,客服在核实了用户身份后,就可以通过详细的错误信息来告之用户,究竟是密码不匹配,还是你的账户不存在,或是别的什么原因。
顶楼上,第一种可以当成数据层方法,可以被多种业务需求调用.
第二种更贴合当前业务,也就是减少了重用可能.
这个方法不能叫用户登录,要叫"通过用户名获取用户实体"包括了"通过用户名和密码获取用户实体"
第一种好。
第一个安全性高,第二个很容易被sql注入 简单的例子:select * from user where username=@userName or 2>1 and userpwd=@userPwd
很高兴你能参与此讨论,不过在参数化的年代,这种低级的sql注入是不会发生的,
比如我用 select userpwd from user where username=@userName or 2>1 句代码是不是能把所有密码取出来呢?呵呵
当参数化后,你那种代码会转化为
select * from user where username='Shinto Ruan or 2>1' and userpwd='123456'