一个网站的登录业务流程到底是怎样的?
阶段一、仅仅比较用户名和密码,非也
故事关键字:sql注入、前端数据校验、JSR303、随机验证码、Base64编码
故事背景: 刚刚接触到网站开发时,我就是这么想的,拿着前端用户输入的用户名和密码去到数据库的用户表中进行查询即可,返回结果不为空就代表用户输入的用户名和密码正确,这样就可以成功登陆啦!当时看上述的业务逻辑非常合理,但也仅仅是我认为的非常合理而已。
我:像我这个人吧,我了解一点sql注入的问题,那么我闲着没事在用户登录的信息输入框恶意输入逻辑字符串,敢问后端你该如何应付啊?
后端:小子,你竟然知道${}
这个人的底细,不行我不能再让${}
你干活了,我要再找一个人,就是#{}
。
我:好家伙!新来的这个人#{}
,我完全没有听说过呀,那该怎么办呢?不然我先把这个家伙给累死,看“后端”还有什么办法!于是我闲着没事我就一直在前台页面一直点击登录,我累死#{}
让他不能在干活了。
后端:别以为我只有一个兄弟,我去找我的前端
好兄弟帮忙,让你这些随意输入不符合规范的用户名和密码根本不可能去请求我的后台,让前端
帮我检查一下,不符合我的标准的没有机会向我发送请求,看看你还有什么办法。
我:呦呵,学聪明了,知道和前端
联盟了。但是别以为只有你有联盟,因为我也有好帮手postman
,我直接从控制台偷看你的后台登录接口,直接调用你的接口也是一样的哦。
后端:呵呵,早就算到你这一步了,兄台可成听闻JSR303
数据校验,我不仅在前端进行数据校验,在后端同样进行数据检查,先生,这一步可曾算到?
我:行,第二步你都算到了,但是即使你聪明绝顶,也顶不住我们人多势众我,我和我同学一起继续在前台输入规范的数据库不存在的账号进行频繁登录,实在不行我花重金让大佬给我写一个自动化的脚本,就要把你的后端给搞崩溃,咋样?
后端:算你厉害!但是你有没有听说过随机动态验证码,专门进行人机验证,把你的自动化脚本变成残疾化,让你还偷奸耍滑,哼!
我:这…这个如何是好?待我想上一想…,你本地项目开发测试肯定使用的是http发送的请求,总所周知http协议以Base64编码传输信息,而Base64编码是可逆的,这不就是明文传输信息吗?我直接窃取你们系统的登录信息,哈哈。
后端:糟糕,还真让他找到漏洞了…
阶段二、四年之后,我与后端再次相遇…
关键字:cookie、session、sessin集群、Redis
故事背景: 四年之后,后端通过结识的cookie
和session
在web开发领域混的风声水起…
我:兄弟,听说这四年来你认识不少牛人啊,能不能介绍介绍?
后端:咋地,最近是不是没有办法攻击我啦,想从我身边的牛人入手?
我:看你说的咱们讨论讨论,这样也能够互相取长补短,共同进步啊!你说对吧。
后端:好吧,看你态度不错就跟你说一说。cookie
是作用于浏览器端,而seeesion
作用在服务器端。上次你也给我提了一个醒,就是我向后端发送http请求存在用户相关信息泄露的问题,因此我想到一个解决办法,就是用户输入账号密码成功登录之后,将用户信息存放到session中,保存成功之后会返回一个JSESSIONID
的cookie
存储到浏览器端,这样的话用户再向后端发送请求只需要携带这个JSESSIONID
,通过这个id向服务器的session中查询对应的用户信息即可。用户信息保存在session中保证了用户信息的安全性。
我:哦,原来如此。但是这样做的话,一旦系统使用用户量很多,服务器的压力岂不是很大,服务器能承受的住吗?
后端:如果用户量很大的话,我只能对服务器采用集群的方式了。
我:但是如果对服务器进行集群,怎么保证每个用户能够正确的到存放自己信息的服务器的session中去查询自己的信息?
后端:这个问题我也想过,之前查阅资料,有人说可以使用session同步复制来解决,这样无论用户请求到哪个服务器都能够查询自己的个人信息,但是我认为这种方式会浪费服务器资源并不是很好的解决方案。
我:对,我也感觉这种方式并不是最好的解决方案。我之前在学习过程中听到过这样一句话:没有什么是添加一层解决不了的 ,我之前了解过一种中间件Redis
,它是一种基于内存存储的key-value
数据库,因为基于内存,所以读写速度非常快,我们可以尝试把用户标识信息存放到Redis中,代替session,这样既可以减轻服务器端的压力,也解决了刚才集群带来的缺陷。
后端:我去,你这想法不错,我直接豁然开朗!
阶段三、听说过JWT吗?
关键字:JWT
故事背景: Redis是基于内存的存储,断电即失,因此Redis的数据维护是重中之重。
后端:好兄弟,你之前推荐的基于Redis存储用户信息我实践过了,效果还不错;但是有一个问题就是Redis的数据持久化维护是个问题,像我这个小小的web项目,感觉使用Redis有点大材小用了。
我:确实,如果是一个普通的web项目使用Redsi确实有点大财小用了。唉,对了,你听说过JWT吗?
后端:那是什么?
我:JWT全称JSON WEB TOKEN
,它是一种token令牌,由标头、负载、秘钥三部分组成,最后对上述三部分进行签名加密,生成一个字符串类型的token,确保信息没有被篡改。生成的token保存在浏览器端,用户每次发送请求,请求头就会携带上这个token,你们后端可以根据秘钥进行解析获取用户的标识信息,这样你们服务端就不用管理这个头疼的用户信息啦。
后端:这个解决方案也不错,我赶紧去试试!