php 给入门新手们填的第一个坑

新入门的小伙伴们。(大佬请移驾, 这里会浪费您宝贵的时间) 注册登录这个逻辑永远是你躲不过的。所有这里说一个登录的大大大大大大坑, 看过的小伙伴不能在踩雷了。

前端有一个朋友发了一段代码给我看(截图图片找了好久没有找到,也贴不出来了 )?因为是朋友给我发的一段代码,真实性不太敢确定,反正我本人接手的项目中没有遇到这样奇葩的代码;不知道我入门的时候是不是也这样写过,如果真的有写过的话,估计看到的大佬会跟我现在的心情一样一样的。

好了我们先说一下那段代码的操作吧。  其实就是一段用户登录的代码(说到这里估计有人就已经想到了啥操作了), 

第一个操作是接收登录表单提交的数据(用的是$_GET['usernam']去接收的)

第二个操作是“select * from users where start = 1”(他用的是tp框架,最终执行的sql语句是这个,我记得跟清楚);   逻辑上不说,但从这条sql语句上来说这里还是可圈可点的  至少他加了一个查询条件呀(就因为这个条件我还在我朋友哪里表扬了他)

第三个操作是循环第二步查询出来的结果,然后用查询出来的数据循环和接收到的用户名去匹配,然后在将匹配到的数据再次进行密码匹配(抛开前面的逻辑不说,至少密码验证的逻辑是对的 )

第四个操作是这个判断如果有匹配到数据就保存session(他这里的session也只仅仅保存了一个用户的id)没有匹配到就返回了登录失败

大概流程就是这样了!!!  大家来找茬 ?

 

 

 

 

 

 

好了 ,接下来我说说上面操作的几点问题之处吧(有未考虑到的地方欢迎指定【有奖】)

第一   接收数据的时候: 登录操作很重要,处理不好黑客、或者测试人员就能简简单单的攻破;  你用get接收参数  不就摆明了告诉人家我有漏洞快来弄我吗?  所以表单提交数据还是用post方式吧,特别还是这种关于用户隐私的账户信息;

第二   本身上面第二步的逻辑上就错误了, 但是还是说一下这个sql语句的问题和建议: 俗话说 一切过早的优化都是恶魔  但是在写sql语句的时候一定要避免使用“*”查询数据,那上面的案例来说(假设users表有20个字段)他查出结果以后实际用到了2个字段(username和password),那么其余的字段多少多余的,主要是影响查询数据的效率,所以遵循一个原则:需要到什么字段就查询出什么字段。  在上面的案例中 那我在错误道路上做的最正确的事就是加了一个查询条件, 对就是查询条件, 写查询条件也是有讲究的,朋友!!

这是我自己一直遵循的原则:如果是多个查询条件, 根据实际情况考虑,sql能根据某一个条件能最少的拿到数据 就将这个条件放在第一位,在考虑第二位和第三位的查询条件(例如  根据start=1 能查出100条数据   根据type = 1能查出30条数据,我们的sql语句一定要这样写:select “username”, “password” from where type = 1 and start = 1) 这里应该明白啥意思了吧;

第三   比较数据的时候,切记不要相信提交数据的真实性, 不管前端是否过滤过数据, 在接收到数据的第一件事就是验证数据的有效性,最基本的是否为空,字符长度是否满足(是否超过数据库定义的字符串长度),手机号码、电子邮箱格式的验证等;  还有一个比较容易忽略的就是提交的数据开头或者结尾含有空格字符,  所有上面用户名匹配时候必须使用trim( $str )这个函数过滤一下;

第四  session是可以保存登录用户的信息,但是要设置一个过期时间,重要的数据不要存放到session中,实时、比较重要的数据(譬如金额、积分)要通过数据库实时的获取,具体session用户百度一下吧, 我这里就不说那么多了

综合上面那么朋友犯错还是停严重的 , 逻辑上的错误大大大的大过代码错误,第一个错误情有可原的话 后面的错误希望小伙伴们看完后就不要在犯错了 。

 

 

 

下面给一个比较常规的注册登录逻辑吧

#注册逻辑

1:前后端最好都要对表单数据进行有效的验证(前端验证是为了减少服务器压力,后端验证是保证数据的有效性),前端可不验证,但是后端的验证必不可少, 表单数据一定要post请求传给后端;

2:注册的账户(用户名、手机号码、邮箱)必须要验证唯一性和有效性(长度、多余的空格、手机号码的格式等), 密码加密(md5加密现在太好反加密了),如果非要用md5加密的话 可以在原始密码的基础上拼接一个时间戳,这样就增加了解密难度,密码在数据库一定要记录密文,不能有明文密码的字段(这样就侵犯了用户的隐私权,虽然用户不太可能会知道)

3:密码的安全性(数字、大写字母、小写字母、特殊符号、密码长度) 密码长度硬性要求最少6位 安全级别最低要求2种字符

4:最后将验证、处理后的数据保存到数据库就好了

 

#登录逻辑

1:登录表单数据一定要post请求传给后端(有必要的话进行序列化),登录的时候最好加图形验证码或图片验证码子类的, 不要直接用户名和密码这两个数据提交(防止通过脚本不断的请求服务)

2:后端接收到数据第一件事永远都是验证数据有效性(你要铭记这句话,你永远也不知道那么“傻X”用户输入的是啥?也不要相信那些“傻X”用户输入的是啥), 验证    验证     验证   !!!

3:正常的登录流程: 首先是通过用户名作为条件去查询数据(条件是 “username” = trim( $_POST['username'] ) ) 为啥要用trim()函数 有些用户确实会习惯性的打空格 就像写作文那样 开头总是会空两格,所有不管有没有我们都要删除多余的空格,只匹配有效的字符。查询的时候不要“*”查询, 在接下来的判断和保存session中用到那些字段就查询出那些字段,如果查询不到可以提示用户账户名错误

4:然后在验证用户的密码是否正常,一般不要将密文反解密为明文比较, 要将注册时的加密算法一样将表单提交的明文密码加密成密文, 让两个密文来比较,错误则可提示密码输入错误

5:如果有图像验证码获取手机验证码等子类的验证需要在查询数据之前验证,如果验证不成功的话 就不用去查数据库的操作了

6:为啥不将用户名和加密后的密文作为条件去查数据库 这样就可以一步到位,查到了就登录成功,没有查到就登录失败;这样可以吗? 可以的,但是不友好,如果没查到的话 你不能友好的提示用户是账户输错了还是密码输错了

7:最后将查询到的用户信息保存到session中就可以了

 

 

 

总结一下吧。 错误谁都会返,不同阶段犯不同错而已,不说别人了 回过头看看自己一年前的代码,也就那样,现在的代码在大佬面前,也就那样,所有加油吧,勇敢的骚年 php入门很简单, 自学过程中真的好疼苦,所有花了点时间,将自己遇到的坑和别的小伙伴遇到的坑插上旗子, 让后来的小伙伴绕道而行

posted on 2020-09-03 14:07  红色的黑  阅读(274)  评论(0)    收藏  举报