PHP实践教程之过滤、验证、转义与密码详解


Posted in PHP onJuly 24, 2017

本文主要给大家介绍的是关于PHP实践之过滤、验证、转义与密码等相关的内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍:

一、过滤、验证和转义

1).不要相信任何来自不受自己直接控制的数据源中的数据。包括但不限于:

  • $_GET
  • $_POST
  • $_REQUEST
  • $_COOKIE
  • $argv
  • php://stdin
  • php://input
  • file_get_contents()
  • 远程数据库
  • 远程API
  • 来自客户端的数据

2).解决办法:过滤输入。删除不安全的字符,在数据到达应用的存储层之前,必须过滤数据。需要过滤的数据包括不限于:HTML、SQL查询和用户资料信息。

  • HTML:使用htmlentities()函数过滤HTML成对应的实体。这个函数会转义制定字符的HTML字符,以便在存储层安全的渲染。正确的使用方式是使用htmlentities($input, ENT_QUOTES, 'UTF-8')过滤输入。或者使用HTML Purifier。缺点是慢
  • SQL查询: 有时必须根据数据构建SQL查询。这时要要使用PDO预处理语句过滤外部数据。
  • 用户资料信息:使用filter_var()filter_input()过滤用户资料信息

3).验证数据:也可以使用filter_var() ,验证成功返回要验证的值,失败返回false。但是这个函数无法验证所有数据,所以可以使用一些验证功能组件。例如aura/filter或者symfony/validator

4)转义输出:任然可以使用htmlentities这个函数,一些模板引擎也自带了转义功能。

密码

       1).绝对不能知道用户的密码。

       2).绝对不要约束用户的密码,要限制的话只限制最小长度。

       3).绝对不能使用电子邮件发送用户的密码。你可以发送一个修改密码的链接,上面带一个token验证是用户本人就行了。

       4).使用bcrypt计算用户密码的哈希值。加密和哈希不是一回事,加密是双向算法,加密的数据可以被解密。但是哈希是单项算法,哈希之后的数据无法被还原,想同的数据哈希之后得到的数据始终是相同的。使用数据库存储通过bcrypt哈希密码之后的值。

       5).使用密码哈希API简化计算密码哈希和验证密码的操作。下面的注册用户的一般操作

POST /register.php HTTP/1.1
Content-Length: 43
Content-type: application/x-www-form-urlencoded

email=xiao@hello.world&password=nihao

下面是接受这个请求的PHP文件

<?php
try {
 $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
 if (!$email) {
  throw new Exception('Invalid email');
 }
 $password = filter_iput(INPUT_POST, 'password');
 if (!$password || mb_strlen($password) < 8) {
  throw new Exception('Password must contain 8+ characters');
 }
 //创建密码的哈希值
 $passwordHash = password_hash(
  $password,
  PASSWORD_DEFAULT,
  ['cost' => 12]
  );

 if ($passwordHash === false) {
  throw new Exception('Password hash failed');
 }

 //创建用户账户,这里是虚构的代码
 $user = new User();
 $user->email = $email;
 $user->password_hash = $passwordHash;
 $user->save();
 header('HTTP/1.1 302 Redirect');
 header('Location: /login.php');
} catch (Exception $e) {
 header('HTTP1.1 400 Bad Request');
 echo $e->getMessage();
}

       6).根据机器的具体计算能力修改password_hash()的第三个值。计算哈希值一般需要0.1s-0.5s。

       7).密码的哈希值存储在varchar(255)类型的数据库列中。

       8).登录用户的一般流程

POST /login.php HTTP1.1
Content-length: 43
Content-Type: application/x-www-form-urlencoded

email=xiao@hello.wordl&pasword=nihao
session_start();
try {
 $email = filter_input(INPUT_POST, 'email');
 $password = filter_iinput(INPUT_POST, 'password');

 $user = User::findByEmail($email);

 if (password_verify($password, $user->password_hash) === false) {
  throw new Exception(''Invalid password);
 }

 //如果需要的话,重新计算密码的哈希值
 $currentHasAlgorithm = PASSWORD_DEFAULT;
 $currentHashOptions = array('cost' => 15);
 $passwordNeedsRehash = password_needs_rehash(
  $user->password_hash,
  $currentHasAlgorithm,
  $currentHasOptions
 );
 if ($passwordNeedsRehash === true) {
  $user->password_hash = password_hash(
   $password,
   $currentHasAlgorithm,
   $currentHasOptions
  );

  $user->save();
 }

 $_SESSION['user_logged_in'] = 'yes';
 $_SESSION['user_email'] = $email;

 header('HTTP/1.1 302 Redirect');
 header('Location: /user-profile.php');
} catch (Exception) {
 header('HTTP/1.1 401 Unauthorized');
 echo $e->getMessage();
}

      9).PHP5.5.0版本之前的密码哈希API无法使用,推荐使用ircmaxell/password-compat组件。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
一个比较简单的PHP 分页分组类
Dec 10 PHP
PHP 引用文件技巧
Mar 02 PHP
php图片处理:加水印、缩略图的实现(自定义函数:watermark、thumbnail)
Dec 02 PHP
php中经典方法实现判断多维数组是否为空
Oct 23 PHP
用来解析.htpasswd文件的PHP类
Sep 05 PHP
使用php将某个目录下面的所有文件罗列出来的方法详解
Jun 21 PHP
php使用post数组的键值创建同名变量并赋值的方法
Apr 03 PHP
PHP7.1方括号数组符号多值复制及指定键值赋值用法分析
Sep 26 PHP
详细解读php的命名空间(二)
Feb 21 PHP
解决tp5在nginx下修改配置访问的问题
Oct 16 PHP
php使用redis的有序集合zset实现延迟队列应用示例
Feb 20 PHP
PHP设计模式之命令模式示例详解
Dec 20 PHP
php实现和c#一致的DES加密解密实例
Jul 24 #PHP
PHP读取CSV大文件导入数据库的实例
Jul 24 #PHP
Yii2.0多文件上传实例说明
Jul 24 #PHP
thinkphp分页集成实例
Jul 24 #PHP
PHP 实现页面静态化的几种方法
Jul 23 #PHP
PHP魔术方法之__call与__callStatic使用方法
Jul 23 #PHP
php魔法函数与魔法常量使用介绍
Jul 23 #PHP
You might like
PHP实现绘制二叉树图形显示功能详解【包括二叉搜索树、平衡树及红黑树】
2017/11/16 PHP
php 中self,this的区别和操作方法实例分析
2019/11/04 PHP
做网页的一些技巧
2007/02/01 Javascript
禁止JQuery中的load方法装载IE缓存中文件的方法
2009/09/11 Javascript
获取网站跟路径的javascript代码(站点及虚拟目录)
2009/10/20 Javascript
[原创]js获取数组任意个不重复的随机数组元素
2010/03/15 Javascript
javascript对talbe进行动态添加、删除、验证实现代码
2012/03/29 Javascript
如何实现textarea里的不同文本显示不同颜色
2014/01/20 Javascript
IE6已终止操作问题的2种情况及解决
2014/04/23 Javascript
JQuery中attr方法和removeAttr方法用法实例
2015/05/18 Javascript
javascript类型系统_正则表达式RegExp类型详解
2016/06/24 Javascript
JavaScript 中 avalon绑定属性总结
2016/10/19 Javascript
ES6概念 ymbol.for()方法
2016/12/25 Javascript
bootstrap table配置参数例子
2017/01/05 Javascript
微信小程序使用radio显示单选项功能【附源码下载】
2017/12/11 Javascript
JavaScript选择排序算法原理与实现方法示例
2018/08/06 Javascript
jQuery zTree插件使用简单教程
2019/08/16 jQuery
原生js实现自定义滚动条
2021/01/20 Javascript
Bootstrap FileInput实现图片上传功能
2021/01/28 Javascript
使用Python压缩和解压缩zip文件的教程
2015/05/06 Python
python使用clear方法清除字典内全部数据实例
2015/07/11 Python
Python2实现的LED大数字显示效果示例
2017/09/04 Python
Python引用计数操作示例
2018/08/23 Python
Python代码实现删除一个list里面重复元素的方法
2019/04/02 Python
Django 实现admin后台显示图片缩略图的例子
2019/07/28 Python
Python的bit_length函数来二进制的位数方法
2019/08/27 Python
Python openpyxl读取单元格字体颜色过程解析
2019/09/03 Python
Python性能测试工具Locust安装及使用
2020/12/01 Python
英国在线花园中心:You Garden
2018/06/03 全球购物
Myprotein亚太地区:欧洲第一在线运动营养品牌
2020/12/20 全球购物
分公司经理岗位职责
2013/11/11 职场文书
马丁路德金演讲稿
2014/05/19 职场文书
中学清明节活动总结
2014/07/04 职场文书
国际会计专业求职信
2014/08/04 职场文书
社区公民道德宣传日活动总结
2015/03/23 职场文书
2015年公务员试用期工作总结
2015/05/28 职场文书