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更改目录及子目录下所有的文件后缀扩展名的代码
Oct 12 PHP
PHP通过iconv将字符串从GBK转换为UTF8字符集
Jul 18 PHP
php&amp;mysql 日期操作小记
Feb 27 PHP
PHP批量采集下载美女图片的实现代码
Jun 03 PHP
PHP对表单提交特殊字符的过滤和处理方法汇总
Feb 18 PHP
codeigniter集成ucenter1.6双向通信的解决办法
Jun 12 PHP
php采用curl实现伪造IP来源的方法
Nov 21 PHP
php安装php_rar扩展实现rar文件读取和解压的方法
Nov 17 PHP
PHP CURL实现模拟登陆并上传文件操作示例
Jan 02 PHP
laravel框架数据库操作、查询构建器、Eloquent ORM操作实例分析
Dec 20 PHP
php文件上传原理与实现方法详解
Dec 20 PHP
MacOS下PHP7.1升级到PHP7.4.15的方法
Feb 22 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
第十节--抽象方法和抽象类
2006/11/16 PHP
PHP执行批量mysql语句的解决方法
2013/05/02 PHP
分享十款最出色的PHP安全开发库中文详细介绍
2015/03/22 PHP
PHP实现权限管理功能示例
2017/09/22 PHP
PHP中的访问修饰符简单比较
2019/02/02 PHP
文字幻灯片
2006/06/26 Javascript
JavaScript随机排序(随即出牌)
2010/09/17 Javascript
JavaScript高级程序设计 阅读笔记(十四) js继承机制的实现
2012/08/14 Javascript
JS/jQuery实现默认显示部分文字点击按钮显示全部内容
2013/05/13 Javascript
javascript实现验证身份证号的有效性并提示
2015/04/30 Javascript
loading动画特效小结
2017/01/22 Javascript
利用Angular+Angular-Ui实现分页(代码加简单)
2017/03/10 Javascript
JavaScript实现的可变动态数字键盘控件方式实例代码
2017/07/15 Javascript
前端图片懒加载(lazyload)的实现方法(提高用户体验)
2017/08/21 Javascript
bootstrap table支持高度百分比的实例代码
2018/02/28 Javascript
Python 连连看连接算法
2008/11/22 Python
Python的for和break循环结构中使用else语句的技巧
2016/05/24 Python
取numpy数组的某几行某几列方法
2018/04/03 Python
pandas 取出表中一列数据所有的值并转换为array类型的方法
2018/04/11 Python
使用Python实现在Windows下安装Django
2018/10/17 Python
python实现dijkstra最短路由算法
2019/01/17 Python
Python中的asyncio代码详解
2019/06/10 Python
python redis连接 有序集合去重的代码
2019/08/04 Python
详解用Python为直方图绘制拟合曲线的两种方法
2019/08/21 Python
Python 异常的捕获、异常的传递与主动抛出异常操作示例
2019/09/23 Python
python利用dlib获取人脸的68个landmark
2019/11/27 Python
使用css3匹配手机屏幕横竖状态
2014/01/27 HTML / CSS
html5 视频播放解决方案
2016/11/06 HTML / CSS
浅析HTML5 Landmark
2020/09/11 HTML / CSS
ORACLE第二个十问
2013/12/14 面试题
系统管理员的职责包括那些?管理的对象是什么?
2013/01/18 面试题
运动会解说词100字
2014/01/31 职场文书
竞选纪律委员演讲稿
2014/09/13 职场文书
初中学生操行评语
2014/12/26 职场文书
仓库保管员岗位职责
2015/02/09 职场文书
爱国之歌(8首)
2019/09/29 职场文书